跟大师学习系统编程---操作系统加载(2)

加载setup.s

    jmpi    go,INITSEG
go: mov ax,cs
    mov ds,ax
    mov es,ax
! put stack at 0x9ff00.
    mov ss,ax
    mov sp,#0xFF00      ! arbitrary value >>512

第1行代码执行时,会修订CS寄存器为0x9000。所以第2~6行语句执行后的效果为当前代码段(CS),数据段(DS, ES),堆栈段的(CS)都是0x9000对应的段内存,即0x90000~0x9FFFF所在的段。第7行将sp指针指向0xff00的位置。由于代码和数据从0x90000往地址增加方向增长,而堆栈从0x9ff00往地址减小方向增长。这个空间对bootsect.s程序来说足够了(其代码和数据区只占用512字节内存)。

说明:sp指针可以调整成更小的值,但调得太小的话,担心堆栈溢出,覆盖代码和数据区。它的最大可能值为0xffff(如果考虑4字节对齐,则为0xfffc)。

! load the setup-sectors directly after the bootblock.
! Note that 'es' is already set up.

load_setup:
    mov dx,#0x0000      ! drive 0, head 0
    mov cx,#0x0002      ! sector 2, track 0
    mov bx,#0x0200      ! address = 512, in INITSEG
    mov ax,#0x0200+SETUPLEN ! service 2, nr of sectors
    int 0x13            ! read it
    jnc ok_load_setup       ! ok - continue
    mov dx,#0x0000
    mov ax,#0x0000      ! reset the diskette
    int 0x13
    j   load_setup

ok_load_setup:

各种段寄存器设置成合适的值以后,就开始加载setup.s程序了,setup.s占4个扇区(SETUPLEN),其在磁盘中的位置为bootsect.s扇区之后(bootsect.s占1个扇区,512字节)。

需要说明的是,操作系统映像(image)在磁盘中是连续存储的(包含bootsect.s,setup.s,以及剩余部分),从(0驱动器,0磁头,0磁道,1扇区)开始,即磁盘的第1个扇区开始。但是setupsect.s, setup.s以及剩下的程序在内存中是分散的。内存中的分布是由bootsect.s和setup.s程序逻辑控制的。

从第7行代码可知,setup.s被加载到了0x9000:0200的位置,即0x90200的位置(偏移512字节),刚好在移动后的bootsect.s后面。实际上这样做也不是必须的,可以加载到0x9000:0400或者0x9000:0600等,只要不覆盖已有的bootsect.s以及不影响未来的剩余映像加载即可。

本程序通过0x13中断将磁盘中的内容读入内存(直接读入4个扇区),此中断程序为BIOS初始化,中断向量在0地址附近。

如果读取失败,则复位磁盘重试。没有查询相关资料,什么情况下读取会失败,复位磁盘重试就能成功吗:)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值