文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>linux-0.00完全注释(一)

linux-0.00完全注释(一)

时间:2007-04-23  来源:mishuang

! PC机上电后,BIOS会将磁盘的前512字节(MBR)加载到内存0x7c00,并从该处开始执行。
! MBR分为三部分:
! 1)0-445  (446字节)
! 2)446-509(64字节)
! 3)510-511(2字节)
! MBR的前446字节代码会加载OS内核
! 446-509字节是磁盘的四个分区表。详细结构请参考C程序
! http://blog.chinaunix.net/u/23177/showart.php?id=206942
! linux-0.00的这个文件只构成了MBR第一部分。没有磁盘分区表。第三部分是由tools/build.c程序写进去的。
!    buf[510]=0x55;
!    buf[511]=0xAA;
! boot.s直接将第二扇区(1扇区等于512字节)开始的17个扇区调入内存0x10000,并跳转到那里以保护模式开始执行。

.globl begtext, begdata, begbss, endtext, enddata, endbss
.text
begtext:
.data
begdata:
.bss
begbss:
.text

! BIOS将这段代码载入到内存的位置
BOOTSEG = 0x07c0
! 实模式下的寻址方式是段寄存器左移四位再加上偏移
SYSSEG  = 0x1000
! 这个值是硬编码进去的,编译好的Image文件是8.5k,正好17个扇区
! 其实去掉MBR这一个扇区,应该载入16个扇区就够了
! 我也试了SYSLEN=16确实可以
SYSLEN  = 17

entry start
start:
! 跳转到标号go。我试图注释掉下面的语句或者通过ax给cs赋值BOOTSEG
! 但是系统就起不来了,还没有想明白为什么
! 在linux-0.11中,MBR中的代码将自身移到段INITSEG,也就是0x9000:0x0000
! 然后,执行jmpi go,#INITSEG
    jmpi    go,#BOOTSEG
go:
    mov    ax,cs
    mov    ds,ax    
    mov    es,ax
    mov    ss,ax
    mov    sp,#0x400        ! arbitrary value >>512

! BIOS 0x13中断用法
! ah=0x02 读磁盘扇区到内存
! al=需读出扇区数
! ch=磁盘柱面号低8位
! cl=开始扇区(0-5);磁盘柱面号高2位(7-8)
! dh=磁头号(若是硬盘最高位置为1)
! ex:bx=数据缓冲区
! 下面的代码利用0x13号BIOS中断调用将从第二扇区开始的17个扇区调入内存0x1000:0x0000

load_system:
    mov    dx,#0x0000
    mov    cx,#0x0002
    mov    ax,#SYSSEG
    mov    es,ax
    mov    bx,#0x0000
    mov    ax,#0x200+SYSLEN
    int     0x13
    jnc    ok_load
    mov    dx,#0x0000
    mov    ax,#0x0000
    int    0x13
    jmp    load_system

ok_load:

! 关中断
    cli

! 装入段描述符

    mov    ax,cs        ! right, forgot this at first. didn't work :-)
    mov    ds,ax
    lidt    idt_48        ! load idt with 0,0
    lgdt    gdt_48        ! load gdt with whatever appropriate

! 对8259芯片进行编程,这部分内容可以参考接口方面的书

    mov    al,#0x11        ! initialization sequence
    out    #0x20,al        ! send it to 8259A-1
    out    #0xA0,al        ! and to 8259A-2
    mov    al,#0x20        ! start of hardware int's (0x20)
    out    #0x21,al
    mov    al,#0x28        ! start of hardware int's 2 (0x28)
    out    #0xA1,al
    mov    al,#0x04        ! 8259-1 is master
    out    #0x21,al
    mov    al,#0x02        ! 8259-2 is slave
    out    #0xA1,al
    mov    al,#0x01        ! 8086 mode for both
    out    #0x21,al
    out    #0xA1,al
    mov    al,#0xFF        ! mask off all interrupts for now
    out    #0x21,al
    out    #0xA1,al

! 设置状态寄存器,进入保护模式
! 在实模式下,内存地址等于段寄存器左移四位加上偏移
! 进入保护模式后,段寄存器的作用变成了gdt表的索引
! 段寄存器低2位为11代表用户态,00代表内核态
! 段寄存器第3位为1代表局部描述符,0代表全局描述符
! 段寄存器高13位表示该段在gdt表中的索引号,因此系统最多有8192个段
! 在文件head.s的tss结构体中cs=0x0f,其他段寄存器都是0x17
! 也就是说所有段都是用户态的局部段,只不过cs使用gdt表的第一项
! 其他段寄存器使用gdt表的第二项

    mov    bx,#SYSSEG      ! loaded place.
    mov    ax,#0x0001    ! protected mode (PE) bit
    lmsw    ax        ! This is it!
    jmpi    0,8        ! jmp offset 0 of segment 8 (cs)

gdt:
    .word    0,0,0,0        ! dummy

    .word    0x07FF        ! 8Mb - limit=2047 (2048*4096=8Mb)
    .word    0x0000        ! base address=0x10000
    .word    0x9A01        ! code read/exec
    .word    0x00C0        ! granularity=4096, 386

    .word    0x07FF        ! 8Mb - limit=2047 (2048*4096=8Mb)
    .word    0x0000        ! base address=0x10000
    .word    0x9201        ! data read/write
    .word    0x00C0        ! granularity=4096, 386

idt_48:
    .word    0        ! idt limit=0
    .word    0,0        ! idt base=0L

gdt_48:
    .word    0x7ff        ! gdt limit=2048, 256 GDT entries
    .word    0x7c00+gdt,0    ! gdt base = 07xxx
    
.text
endtext:
.data
enddata:
.bss
endbss:
 
相关阅读 更多 +
排行榜 更多 +
超级瘦身大师

超级瘦身大师

休闲益智 下载
迅猛兔加速器

迅猛兔加速器

游戏工具 下载
弹琴吧

弹琴吧

学习教育 下载