From real mode to protected mode

本文详细解析了LILO启动过程中的关键步骤,包括如何处理超过4扇区的设置代码及数据,验证设置签名,等待A20地址线启用,以及如何开启保护模式并跳转到物理地址。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

bootsect or LILO will jump to this setup function which located at 0x9020:0000.

 

/* Because LILO only load 4 sectors of setup to 0x90200, so left will be copied to 0x10000 with system if setup has more than 4 sectors.  move rest of setup code/data from 0x10000 to 0x90800*/

! We now have to find the rest of the setup code/data
bad_sig:
        mov     ax,cs           ! aka #SETUPSEG
        sub     ax,#DELTA_INITSEG ! aka #INITSEG
        mov     ds,ax
        xor     bh,bh
        mov     bl,[497]        ! get setup sects from boot sector
        sub     bx,#4           ! LILO loads 4 sectors of setup
        shl     bx,#8           ! convert to words
        mov     cx,bx
        shr     bx,#3           ! convert to segment
        add     bx,#SYSSEG
        seg cs
        mov     start_sys_seg,bx          /* update the correct start address of system */

! Move rest of setup code/data to here
        mov     di,#2048        ! four sectors loaded by LILO
        sub     si,si
        mov     ax,cs           ! aka #SETUPSEG
        mov     es,ax
        mov     ax,#SYSSEG
        mov     ds,ax
        rep
        movsw

        mov     ax,cs           ! aka #SETUPSEG
        mov     ds,ax
        cmp     setup_sig1,#SIG1
        jne     no_sig
        cmp     setup_sig2,#SIG2
        jne     no_sig
        jmp     good_sig      /* completed successfully */

 

/* if a20 is turned off, then only 20bit address pin is available, that it, maximun adress is 0xffff0 + 0xffff = 0x10ffef, and contents of 0x00000 - 0x0ffef is the same with 0x10000 - 0x10ffef. so following check whether contents of 0x0007c is the same with 0x1007c, if not the same, then A20 is turned on */

! wait until a20 really *is* enabled; it can take a fair amount of
! time on certain systems; Toshiba Tecras are known to have this
! problem.  The memory location used here is the int 0x1f vector,
! which should be safe to use; any *unused* memory location < 0xfff0
! should work here.

#define TEST_ADDR 0x7c

        push    ds
        xor     ax,ax                   ! segment 0x0000
        mov     ds,ax
        dec     ax                      ! segment 0xffff (HMA)
        mov     gs,ax
        mov     bx,[TEST_ADDR]          ! we want to restore the value later
a20_wait:
        inc     ax
        mov     [TEST_ADDR],ax
        seg     gs
        cmp     ax,[TEST_ADDR+0x10]          /* 0xffff0 + 0x008c = 0x10007c */
        je      a20_wait                ! loop until no longer aliased
        mov     [TEST_ADDR],bx          ! restore original value
        pop     ds

 

/* turn on PE bit, and jump to physical address: 0x100000 (bzImage) or 0x1000 (zImage) */

        mov     ax,#1           ! protected mode (PE) bit
        lmsw    ax              ! This is it!
        jmp     flush_instr
flush_instr:
        xor     bx,bx           ! Flag to indicate a boot

! NOTE: For high loaded big kernels we need a
!       jmpi    0x100000,__KERNEL_CS
!
!       but we yet haven't reloaded the CS register, so the default size
!       of the target offset still is 16 bit.
!       However, using an operant prefix (0x66), the CPU will properly
!       take our 48 bit far pointer. (INTeL 80386 Programmer's Reference
!       Manual, Mixing 16-bit and 32-bit code, page 16-6)
        db      0x66,0xea       ! prefix + jmpi-opcode
code32: dd      0x1000          ! will be set to 0x100000 for big kernels
        dw      __KERNEL_CS

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值