凌云窟
南山巅上火麟烈,北海潜深雪饮寒。可怜两锋未缘见,雪刀封隐孤剑鸣。
<2006年8月>
303112345
6789101112
13141516171819
20212223242526
272829303112
3456789

留言簿(0)

随笔分类

随笔档案

文章档案

相册

简历下载

搜索

最新评论

阅读排行榜

评论排行榜

 
VC知识库BLOG   首页  新随笔  联系  聚合  登录 
  随笔-22 文章-0 评论-38 Trackbacks-0
2006年8月31日
  这只是mpx386.asm文件的一部分内容,随着学习的深入我会把余下部分的注解也写下来。不过有一点很抱歉,我的这个注解主要是写给自己看,以免以后遗忘后无从下手。所以注解未免太个人化,不太容易懂。敬请谅解!

!在阅读这份代码之前,必须了解cpu的保护模式、GDT、LDT、IDT等相关概念。
.sect .text
!*===========================================================================*
!*                MINIX                         *
!*===========================================================================*
MINIX:                
! this is the entry point for the MINIX kernel
    jmp    over_flags    
! skip over the next few bytes
    .data2    CLICK_SHIFT    
! for the monitor: memory granularity
flags:
    .data2    
0x01FD        ! boot monitor flags:
                
!    call in 386 mode, make bss, make stack,
                
!    load high, don't patch, will return,
                !    uses generic INT, memory vector,
                
!    new boot code return
    nop            
! extra byte to sync up disassembler
over_flags:

!在minix中将引导kernel也就是MINIX标签前的执行代码称之为mointor。
!The monitor sets CS to the kernel code, DS to kernel data, ES to a "flat 
!4G" descriptor that address all memory simply from 0 up, and SS still 
!points to the monitor's stack. 

! Set up a C stack frame on the monitor stack.  (The monitor sets cs and ds
! right.  The ss descriptor still references the monitor data segment.)
    movzx    esp, sp        
! monitor stack is a 16 bit stack
    push    ebp
    mov    ebp, esp
    push    esi
    push    edi
    cmp    
4(ebp), 0    ! monitor return vector is
    jz    noret        
! nonzero if return possible
    inc    (_mon_return)
noret:    mov    (_mon_sp), esp    
! save stack pointer for later return

! Copy the monitor global descriptor table to the address space of kernel and
! switch over to it.  Prot_init() can then update it with immediate effect.

    sgdt    (_gdt
+GDT_SELECTOR)        ! get the monitor gdtr
    mov    esi, (_gdt
+GDT_SELECTOR+2)    ! absolute address of GDT
    mov    ebx, _gdt            
! address of kernel GDT
    mov    ecx, 
8*8            ! copying eight descriptors
    
!_gdt是位于kernel数据段内的GDT。
    
!GDT_SELECTOR(16bits)是GDT的段选择子,他的高13位是段描述符在GDT/LDT中的下标索引。
    
!sgdt读出gdtr寄存器到操作数地址,gdtr = 32bitsbaseAddr +16bitsLimit。
    
!(_gdt+GDT_SELECTOR+2= gdt's baseAddr
copygdt:
 eseg    movb    al, (esi)          
!esi保留的是monitor的GDT的偏移地址。它不位于kernel数据段内。所以es:si
                                   
!ES to a "flat 4G" descriptor that address all memory simply from 0 up
    movb    (ebx), al
    inc    esi
    inc    ebx
    loop    copygdt
    mov    eax, (_gdt
+DS_SELECTOR+2)    ! base of kernel data. _gdt+DS_SELECTOR+2 = 段基址的低24位
    and    eax, 
0x00FFFFFF            ! only 24 bits
    add    eax, _gdt            
! eax = vir2phys(gdt)
    mov    (_gdt
+GDT_SELECTOR+2), eax    ! set base of GDT
    lgdt    (_gdt
+GDT_SELECTOR)        ! switch over to kernel GDT
    
!GDTR内是GDT的物理地址,而_gdt位于kernel的数据段内,所以
    
!kernel's GDTR = kernel数据段的基地址+_gdt偏移地址

! Locate boot parameters, set up kernel segment registers and stack.
    mov    ebx, 
8(ebp)    ! boot parameters offset
    mov    edx, 
12(ebp)    ! boot parameters length
    mov    eax, 
16(ebp)    ! address of a.out headers
    mov    (_aout), eax
    mov    ax, ds        
! kernel data
    mov    es, ax
    mov    fs, ax
    mov    gs, ax
    mov    ss, ax
    mov    esp, k_stktop    
! set sp to point to the top of kernel stack

! Call C startup code to set up a proper environment to run main().
    push    edx
    push    ebx
    push    SS_SELECTOR
    push    DS_SELECTOR
    push    CS_SELECTOR
    call    _cstart        
! cstart(cs, ds, mds, parmoff, parmlen)
    add    esp, 
5*4

! Reload gdtr, idtr and the segment registers to global descriptor table set
! up by prot_init().

    lgdt    (_gdt
+GDT_SELECTOR)
    lidt    (_gdt
+IDT_SELECTOR)

    jmpf    CS_SELECTOR:csinit
csinit:
    o16    mov    ax, DS_SELECTOR
    mov    ds, ax
    mov    es, ax
    mov    fs, ax
    mov    gs, ax
    mov    ss, ax
    o16    mov    ax, TSS_SELECTOR    
! no other TSS is used
    ltr    ax                      
! LTR指令是专门用于装载任务状态段寄存器TR的指令。
                                
!该指令的操作数是对应TSS段描述符的选择子。LTR指令
                                
!从GDT中取出相应的TSS段描述符,把TSS段描述符的基地址
                                
!和界限等信息装入TR的高速缓冲寄存器中。 
    push    
0            ! set flags to known good state
    popf                
! esp, clear nested task and int enable

    jmp    _main            
! main()

发表于 2006-08-31 16:42 莫问春秋 阅读(2455) | 评论 (0)编辑 收藏