⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 00000050.htm

📁 一份很好的linux入门资料
💻 HTM
📖 第 1 页 / 共 2 页
字号:
<HTML><HEAD>  <TITLE>BBS水木清华站∶精华区</TITLE></HEAD><BODY><CENTER><H1>BBS水木清华站∶精华区</H1></CENTER>发信人:&nbsp;seis&nbsp;(矛),&nbsp;信区:&nbsp;Linux&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>标&nbsp;&nbsp;题:&nbsp;Linux操作系统内核引导程序详细剖析&nbsp;&nbsp;<BR>发信站:&nbsp;BBS&nbsp;水木清华站&nbsp;(Fri&nbsp;Feb&nbsp;&nbsp;2&nbsp;14:12:43&nbsp;2001)&nbsp;<BR>&nbsp;<BR>&nbsp;<BR>  这段程序是Linux操作系统启动boot程序,其思想原理可参看本人翻译的《Linux内核&nbsp;<BR>漫游》一篇。&nbsp;&nbsp;<BR>&nbsp;<BR>中文注释:赵炯&nbsp;<A HREF="mailto:gohigh@shtdu.edu.cn">gohigh@shtdu.edu.cn</A>&nbsp;www.freedove.com&nbsp;&nbsp;<BR>&nbsp;<BR>&nbsp;<BR>!&nbsp;bootsect.s&nbsp;(c)&nbsp;1991,&nbsp;1992&nbsp;Linus&nbsp;Torvalds&nbsp;版权所有&nbsp;&nbsp;<BR>!&nbsp;Drew&nbsp;Eckhardt修改过&nbsp;&nbsp;<BR>!&nbsp;Bruce&nbsp;Evans&nbsp;(bde)修改过&nbsp;&nbsp;<BR>!&nbsp;&nbsp;<BR>!&nbsp;bootsect.s&nbsp;被bios-启动子程序加载至0x7c00&nbsp;(31k)处,并将自己&nbsp;&nbsp;<BR>!&nbsp;移到了地址0x90000&nbsp;(576k)处,并跳转至那里。&nbsp;&nbsp;<BR>!&nbsp;&nbsp;<BR>!&nbsp;bde&nbsp;-&nbsp;不能盲目地跳转,有些系统可能只有512k的低&nbsp;&nbsp;<BR>!&nbsp;内存。使用中断0x12来获得(系统的)最高内存、等。&nbsp;&nbsp;<BR>!&nbsp;&nbsp;<BR>!&nbsp;它然后使用BIOS中断将setup直接加载到自己的后面(0x90200)(576.5k),&nbsp;&nbsp;<BR>!&nbsp;并将系统加载到地址0x10000处。&nbsp;&nbsp;<BR>!&nbsp;&nbsp;<BR>!&nbsp;注意!&nbsp;目前的内核系统最大长度限制为(8*65536-4096)(508k)字节长,即使是在&nbsp;&nbsp;<BR>!&nbsp;将来这也是没有问题的。我想让它保持简单明了。这样508k的最大内核长度应该&nbsp;&nbsp;<BR>!&nbsp;是足够了,尤其是这里没有象minix中一样包含缓冲区高速缓冲(而且尤其是现在&nbsp;&nbsp;<BR>!&nbsp;内核是压缩的&nbsp;:-)&nbsp;&nbsp;<BR>!&nbsp;&nbsp;<BR>!&nbsp;加载程序已经做的尽量地简单了,所以持续的读出错将导致死循环。只能手工重启。&nbsp;&nbsp;<BR>!&nbsp;只要可能,通过一次取得整个磁道,加载过程可以做的很快的。&nbsp;&nbsp;<BR>&nbsp;<BR>#include&nbsp;/*&nbsp;为取得CONFIG_ROOT_RDONLY参数&nbsp;*/&nbsp;&nbsp;<BR>!!&nbsp;config.h中(即autoconf.h中)没有CONFIG_ROOT_RDONLY定义!!!?&nbsp;&nbsp;<BR>&nbsp;<BR>#include&nbsp;&nbsp;<BR>&nbsp;<BR>.text&nbsp;&nbsp;<BR>&nbsp;<BR>SETUPSECS&nbsp;=&nbsp;4&nbsp;!&nbsp;默认的setup程序扇区数(setup-sectors)的默认值;&nbsp;&nbsp;<BR>&nbsp;<BR>BOOTSEG&nbsp;=&nbsp;0x7C0&nbsp;!&nbsp;bootsect的原始地址;&nbsp;&nbsp;<BR>&nbsp;<BR>INITSEG&nbsp;=&nbsp;DEF_INITSEG&nbsp;!&nbsp;将bootsect程序移到这个段处(0x9000)&nbsp;-&nbsp;避开;&nbsp;&nbsp;<BR>SETUPSEG&nbsp;=&nbsp;DEF_SETUPSEG&nbsp;!&nbsp;设置程序(setup)从这里开始(0x9020);&nbsp;&nbsp;<BR>SYSSEG&nbsp;=&nbsp;DEF_SYSSEG&nbsp;!&nbsp;系统加载至0x1000(65536)(64k)段处;&nbsp;&nbsp;<BR>SYSSIZE&nbsp;=&nbsp;DEF_SYSSIZE&nbsp;!&nbsp;系统的大小(0x7F00):&nbsp;要加载的16字节为一节的数;&nbsp;&nbsp;<BR>!!&nbsp;以上4个DEF_参数定义在boot.h中:&nbsp;&nbsp;<BR>!!&nbsp;DEF_INITSEG&nbsp;0x9000&nbsp;&nbsp;<BR>!!&nbsp;DEF_SYSSEG&nbsp;0x1000&nbsp;&nbsp;<BR>!!&nbsp;DEF_SETUPSEG&nbsp;0x9020&nbsp;&nbsp;<BR>!!&nbsp;DEF_SYSSIZE&nbsp;0x7F00&nbsp;(=32512=31.75k)*16=508k&nbsp;&nbsp;<BR>&nbsp;<BR>!&nbsp;ROOT_DEV&nbsp;&amp;&nbsp;SWAP_DEV&nbsp;现在是由&quot;build&quot;中编制的;&nbsp;&nbsp;<BR>ROOT_DEV&nbsp;=&nbsp;0&nbsp;&nbsp;<BR>SWAP_DEV&nbsp;=&nbsp;0&nbsp;&nbsp;<BR>#ifndef&nbsp;SVGA_MODE&nbsp;&nbsp;<BR>#define&nbsp;SVGA_MODE&nbsp;ASK_VGA&nbsp;&nbsp;<BR>#endif&nbsp;&nbsp;<BR>#ifndef&nbsp;RAMDISK&nbsp;&nbsp;<BR>#define&nbsp;RAMDISK&nbsp;0&nbsp;&nbsp;<BR>#endif&nbsp;&nbsp;<BR>#ifndef&nbsp;CONFIG_ROOT_RDONLY&nbsp;&nbsp;<BR>#define&nbsp;CONFIG_ROOT_RDONLY&nbsp;1&nbsp;&nbsp;<BR>#endif&nbsp;&nbsp;<BR>&nbsp;<BR>!&nbsp;ld86&nbsp;需要一个入口标识符,这和通常的一样;&nbsp;&nbsp;<BR>.globl&nbsp;_main&nbsp;&nbsp;<BR>_main:&nbsp;&nbsp;<BR>#if&nbsp;0&nbsp;/*&nbsp;调试程序的异常分支,除非BIOS古怪(比如老的HP机)否则是无害的&nbsp;*/&nbsp;&nbsp;<BR>int&nbsp;3&nbsp;&nbsp;<BR>#endif&nbsp;&nbsp;<BR>mov&nbsp;ax,#BOOTSEG&nbsp;!!&nbsp;将ds段寄存器置为0x7C0;&nbsp;&nbsp;<BR>mov&nbsp;ds,ax&nbsp;&nbsp;<BR>mov&nbsp;ax,#INITSEG&nbsp;!!&nbsp;将es段寄存器置为0x9000;&nbsp;&nbsp;<BR>mov&nbsp;es,ax&nbsp;&nbsp;<BR>mov&nbsp;cx,#256&nbsp;!!&nbsp;将cx计数器置为256(要移动256个字,&nbsp;512字节);&nbsp;&nbsp;<BR>sub&nbsp;si,si&nbsp;!!&nbsp;源地址&nbsp;ds:si=0x07C0:0x0000;&nbsp;&nbsp;<BR>sub&nbsp;di,di&nbsp;!!&nbsp;目的地址es:di=0x9000:0x0000;&nbsp;&nbsp;<BR>cld&nbsp;!!&nbsp;清方向标志;&nbsp;&nbsp;<BR>rep&nbsp;!!&nbsp;将这段程序从0x7C0:0(31k)移至0x9000:0(576k)处;&nbsp;&nbsp;<BR>movsw&nbsp;!!&nbsp;共256个字(512字节)(0x200长);&nbsp;&nbsp;<BR>jmpi&nbsp;go,INITSEG&nbsp;!!&nbsp;间接跳转至移动后的本程序go处;&nbsp;&nbsp;<BR>&nbsp;<BR>!&nbsp;ax和es现在已经含有INITSEG的值(0x9000);&nbsp;&nbsp;<BR>&nbsp;<BR>go:&nbsp;mov&nbsp;di,#0x4000-12&nbsp;!&nbsp;0x4000(16k)是&gt;=bootsect&nbsp;+&nbsp;setup&nbsp;的长度&nbsp;+&nbsp;&nbsp;<BR>!&nbsp;+&nbsp;堆栈的长度&nbsp;的任意的值;&nbsp;&nbsp;<BR>!&nbsp;12&nbsp;是磁盘参数块的大小&nbsp;es:di=0x94000-12=592k-12;&nbsp;&nbsp;<BR>&nbsp;<BR>!&nbsp;bde&nbsp;-&nbsp;将0xff00改成了0x4000以从0x6400处使用调试程序(bde)。如果&nbsp;&nbsp;<BR>!&nbsp;我们检测过最高内存的话就不用担心这事了,还有,我的BIOS可以被配置为将wini驱动&nbsp;<BR>表&nbsp;&nbsp;<BR>!&nbsp;放在内存高端而不是放在向量表中。老式的堆栈区可能会搞乱驱动表;&nbsp;&nbsp;<BR>&nbsp;<BR>mov&nbsp;ds,ax&nbsp;!&nbsp;置ds数据段为0x9000;&nbsp;&nbsp;<BR>mov&nbsp;ss,ax&nbsp;!&nbsp;置堆栈段为0x9000;&nbsp;&nbsp;<BR>mov&nbsp;sp,di&nbsp;!&nbsp;置堆栈指针INITSEG:0x4000-12处;&nbsp;&nbsp;<BR>/*&nbsp;&nbsp;<BR>*&nbsp;许多BIOS的默认磁盘参数表将不能&nbsp;&nbsp;<BR>*&nbsp;进行扇区数大于在表中指定&nbsp;&nbsp;<BR>*&nbsp;的最大扇区数(&nbsp;-&nbsp;在某些情况下&nbsp;&nbsp;<BR>*&nbsp;这意味着是7个扇区)后面的多扇区的读操作。&nbsp;&nbsp;<BR>*&nbsp;&nbsp;<BR>*&nbsp;由于单个扇区的读操作是很慢的而且当然是没问题的,&nbsp;&nbsp;<BR>*&nbsp;我们必须在RAM中(为第一个磁盘)创建新的参数表。&nbsp;&nbsp;<BR>*&nbsp;我们将把最大扇区数设置为36&nbsp;-&nbsp;我们在一个ED&nbsp;2.88驱动器上所能&nbsp;&nbsp;<BR>*&nbsp;遇到的最大值。&nbsp;&nbsp;<BR>*&nbsp;&nbsp;<BR>*&nbsp;此值太高是没有任何害处的,但是低的话就会有问题了。&nbsp;&nbsp;<BR>*&nbsp;&nbsp;<BR>*&nbsp;段寄存器是这样的:&nbsp;ds=es=ss=cs&nbsp;-&nbsp;INITSEG,(=0X9000)&nbsp;&nbsp;<BR>*&nbsp;fs&nbsp;=&nbsp;0,&nbsp;gs没有用到。&nbsp;&nbsp;<BR>*/&nbsp;&nbsp;<BR>&nbsp;<BR>!&nbsp;上面执行重复操作(rep)以后,cx为0;&nbsp;&nbsp;<BR>&nbsp;<BR>mov&nbsp;fs,cx&nbsp;!!&nbsp;置fs段寄存器=0;&nbsp;&nbsp;<BR>mov&nbsp;bx,#0x78&nbsp;!&nbsp;fs:bx是磁盘参数表的地址;&nbsp;&nbsp;<BR>push&nbsp;ds&nbsp;&nbsp;<BR>seg&nbsp;fs&nbsp;&nbsp;<BR>lds&nbsp;si,(bx)&nbsp;!&nbsp;ds:si是源地址;&nbsp;&nbsp;<BR>!!&nbsp;将fs:bx地址所指的指针值放入ds:si中;&nbsp;&nbsp;<BR>mov&nbsp;cl,#6&nbsp;!&nbsp;拷贝12个字节到0x9000:0x4000-12开始处;&nbsp;&nbsp;<BR>cld&nbsp;&nbsp;<BR>push&nbsp;di&nbsp;!!&nbsp;指针0x9000:0x4000-12处;&nbsp;&nbsp;<BR>&nbsp;<BR>rep&nbsp;&nbsp;<BR>movsw&nbsp;&nbsp;<BR>&nbsp;<BR>pop&nbsp;di&nbsp;!!&nbsp;di仍指向0x9000:0x4000-12处(参数表开始处);&nbsp;&nbsp;<BR>pop&nbsp;si&nbsp;!!&nbsp;ds&nbsp;=&gt;&nbsp;si=INITSEG(=0X9000);&nbsp;&nbsp;<BR>&nbsp;<BR>movb&nbsp;4(di),*36&nbsp;!&nbsp;修正扇区计数值;&nbsp;&nbsp;<BR>&nbsp;<BR>seg&nbsp;fs&nbsp;&nbsp;<BR>mov&nbsp;(bx),di&nbsp;!!&nbsp;修改fs:bx(0000:0x0078)处磁盘参数表的地址为0x9000:0x4000-12;&nbsp;&nbsp;<BR>seg&nbsp;fs&nbsp;&nbsp;<BR>mov&nbsp;2(bx),es&nbsp;&nbsp;<BR>&nbsp;<BR>!&nbsp;将setup程序所在的扇区(setup-sectors)直接加载到boot块的后面。!!&nbsp;0x90200开始处&nbsp;<BR>;&nbsp;&nbsp;<BR>!&nbsp;注意,es已经设置好了。&nbsp;&nbsp;<BR>!&nbsp;同样经过rep循环后cx为0&nbsp;&nbsp;<BR>&nbsp;<BR>load_setup:&nbsp;&nbsp;<BR>xor&nbsp;ah,ah&nbsp;!&nbsp;复位软驱(FDC);&nbsp;&nbsp;<BR>xor&nbsp;dl,dl&nbsp;&nbsp;<BR>int&nbsp;0x13&nbsp;&nbsp;<BR>&nbsp;<BR>xor&nbsp;dx,dx&nbsp;!&nbsp;驱动器0,&nbsp;磁头0;&nbsp;&nbsp;<BR>mov&nbsp;cl,#0x02&nbsp;!&nbsp;从扇区2开始,磁道0;&nbsp;&nbsp;<BR>mov&nbsp;bx,#0x0200&nbsp;!&nbsp;置数据缓冲区地址=es:bx=0x9000:0x200;&nbsp;&nbsp;<BR>!&nbsp;在INITSEG段中,即0x90200处;&nbsp;&nbsp;<BR>mov&nbsp;ah,#0x02&nbsp;!&nbsp;要调用功能号2(读操作);&nbsp;&nbsp;<BR>mov&nbsp;al,setup_sects&nbsp;!&nbsp;要读入的扇区数SETUPSECS=4;&nbsp;&nbsp;<BR>!&nbsp;(假释所有数据都在磁头0、磁道0);&nbsp;&nbsp;<BR>int&nbsp;0x13&nbsp;!&nbsp;读操作;&nbsp;&nbsp;<BR>jnc&nbsp;ok_load_setup&nbsp;!&nbsp;ok则继续;&nbsp;&nbsp;<BR>&nbsp;<BR>push&nbsp;ax&nbsp;!&nbsp;否则显示出错信息。保存ah的值(功能号2);&nbsp;&nbsp;<BR>call&nbsp;print_nl&nbsp;!!&nbsp;打印换行;&nbsp;&nbsp;<BR>mov&nbsp;bp,sp&nbsp;!!&nbsp;bp将作为调用print_hex的参数;&nbsp;&nbsp;<BR>call&nbsp;print_hex&nbsp;!!&nbsp;打印bp所指的数据;&nbsp;&nbsp;<BR>pop&nbsp;ax&nbsp;&nbsp;<BR>&nbsp;<BR>jmp&nbsp;load_setup&nbsp;!!&nbsp;重试!&nbsp;&nbsp;<BR>&nbsp;<BR>!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!&nbsp;&nbsp;<BR>!!INT&nbsp;13&nbsp;-&nbsp;DISK&nbsp;-&nbsp;READ&nbsp;SECTOR(S)&nbsp;INTO&nbsp;MEMORY&nbsp;&nbsp;<BR>!!&nbsp;AH&nbsp;=&nbsp;02h&nbsp;&nbsp;<BR>!!&nbsp;AL&nbsp;=&nbsp;number&nbsp;of&nbsp;sectors&nbsp;to&nbsp;read&nbsp;(must&nbsp;be&nbsp;nonzero)&nbsp;&nbsp;<BR>!!&nbsp;CH&nbsp;=&nbsp;low&nbsp;eight&nbsp;bits&nbsp;of&nbsp;cylinder&nbsp;number&nbsp;&nbsp;<BR>!!&nbsp;CL&nbsp;=&nbsp;sector&nbsp;number&nbsp;1-63&nbsp;(bits&nbsp;0-5)&nbsp;&nbsp;<BR>!!&nbsp;high&nbsp;two&nbsp;bits&nbsp;of&nbsp;cylinder&nbsp;(bits&nbsp;6-7,&nbsp;hard&nbsp;disk&nbsp;only)&nbsp;&nbsp;<BR>!!&nbsp;DH&nbsp;=&nbsp;head&nbsp;number&nbsp;&nbsp;<BR>!!&nbsp;DL&nbsp;=&nbsp;drive&nbsp;number&nbsp;(bit&nbsp;7&nbsp;set&nbsp;for&nbsp;hard&nbsp;disk)&nbsp;&nbsp;<BR>!!&nbsp;ES:BX&nbsp;-&gt;&nbsp;data&nbsp;buffer&nbsp;&nbsp;<BR>!!&nbsp;Return:&nbsp;CF&nbsp;set&nbsp;on&nbsp;error&nbsp;&nbsp;<BR>!!&nbsp;if&nbsp;AH&nbsp;=&nbsp;11h&nbsp;(corrected&nbsp;ECC&nbsp;error),&nbsp;AL&nbsp;=&nbsp;burst&nbsp;length&nbsp;&nbsp;<BR>!!&nbsp;CF&nbsp;clear&nbsp;if&nbsp;successful&nbsp;&nbsp;<BR>!!&nbsp;AH&nbsp;=&nbsp;status&nbsp;(see&nbsp;#00234)&nbsp;&nbsp;<BR>!!&nbsp;AL&nbsp;=&nbsp;number&nbsp;of&nbsp;sectors&nbsp;transferred&nbsp;(only&nbsp;valid&nbsp;if&nbsp;CF&nbsp;set&nbsp;for&nbsp;some&nbsp;&nbsp;<BR>!!&nbsp;BIOSes)&nbsp;&nbsp;<BR>!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!&nbsp;&nbsp;<BR>&nbsp;<BR>&nbsp;<BR>ok_load_setup:&nbsp;&nbsp;<BR>&nbsp;<BR>!&nbsp;取得磁盘驱动器参数,特别是每磁道扇区数(nr&nbsp;of&nbsp;sectors/track);&nbsp;&nbsp;<BR>&nbsp;<BR>#if&nbsp;0&nbsp;&nbsp;<BR>&nbsp;<BR>!&nbsp;bde&nbsp;-&nbsp;Phoenix&nbsp;BIOS手册中提到功能0x08只对硬盘起作用。&nbsp;&nbsp;<BR>!&nbsp;但它对于我的一个BIOS(1987&nbsp;Award)不起作用。&nbsp;&nbsp;<BR>!&nbsp;不检查错误码是致命的错误。&nbsp;&nbsp;<BR>&nbsp;<BR>xor&nbsp;dl,dl&nbsp;&nbsp;<BR>mov&nbsp;ah,#0x08&nbsp;!&nbsp;AH=8用于取得驱动器参数;&nbsp;&nbsp;<BR>int&nbsp;0x13&nbsp;&nbsp;<BR>xor&nbsp;ch,ch&nbsp;&nbsp;<BR>&nbsp;<BR>!!!!!!!!!!!!!!!!!!!!!!!!!!!&nbsp;&nbsp;<BR>!!&nbsp;INT&nbsp;13&nbsp;-&nbsp;DISK&nbsp;-&nbsp;GET&nbsp;DRIVE&nbsp;PARAMETERS&nbsp;(PC,XT286,CONV,PS,ESDI,SCSI)&nbsp;&nbsp;<BR>!!&nbsp;AH&nbsp;=&nbsp;08h&nbsp;&nbsp;<BR>!!&nbsp;DL&nbsp;=&nbsp;drive&nbsp;(bit&nbsp;7&nbsp;set&nbsp;for&nbsp;hard&nbsp;disk)&nbsp;&nbsp;<BR>!!Return:&nbsp;CF&nbsp;set&nbsp;on&nbsp;error&nbsp;&nbsp;<BR>!!&nbsp;AH&nbsp;=&nbsp;status&nbsp;(07h)&nbsp;(see&nbsp;#00234)&nbsp;&nbsp;<BR>!!&nbsp;CF&nbsp;clear&nbsp;if&nbsp;successful&nbsp;&nbsp;<BR>!!&nbsp;AH&nbsp;=&nbsp;00h&nbsp;&nbsp;<BR>!!&nbsp;AL&nbsp;=&nbsp;00h&nbsp;on&nbsp;at&nbsp;least&nbsp;some&nbsp;BIOSes&nbsp;&nbsp;<BR>!!&nbsp;BL&nbsp;=&nbsp;drive&nbsp;type&nbsp;(AT/PS2&nbsp;floppies&nbsp;only)&nbsp;(see&nbsp;#00242)&nbsp;&nbsp;<BR>!!&nbsp;CH&nbsp;=&nbsp;low&nbsp;eight&nbsp;bits&nbsp;of&nbsp;maximum&nbsp;cylinder&nbsp;number&nbsp;&nbsp;<BR>!!&nbsp;CL&nbsp;=&nbsp;maximum&nbsp;sector&nbsp;number&nbsp;(bits&nbsp;5-0)&nbsp;&nbsp;<BR>!!&nbsp;high&nbsp;two&nbsp;bits&nbsp;of&nbsp;maximum&nbsp;cylinder&nbsp;number&nbsp;(bits&nbsp;7-6)&nbsp;&nbsp;<BR>!!&nbsp;DH&nbsp;=&nbsp;maximum&nbsp;head&nbsp;number&nbsp;&nbsp;<BR>!!&nbsp;DL&nbsp;=&nbsp;number&nbsp;of&nbsp;drives&nbsp;&nbsp;<BR>!!&nbsp;ES:DI&nbsp;-&gt;&nbsp;drive&nbsp;parameter&nbsp;table&nbsp;(floppies&nbsp;only)&nbsp;&nbsp;<BR>!!!!!!!!!!!!!!!!!!!!!!!!!!!!&nbsp;&nbsp;<BR>&nbsp;<BR>#else&nbsp;&nbsp;<BR>&nbsp;<BR>!&nbsp;好象没有BIOS调用可取得扇区数。如果扇区36可以读就推测是36个扇区,&nbsp;&nbsp;<BR>!&nbsp;如果扇区18可读就推测是18个扇区,如果扇区15可读就推测是15个扇区,&nbsp;&nbsp;<BR>!&nbsp;否则推测是9.&nbsp;[36,&nbsp;18,&nbsp;15,&nbsp;9]&nbsp;&nbsp;<BR>&nbsp;<BR>mov&nbsp;si,#disksizes&nbsp;!&nbsp;ds:si-&gt;要测试扇区数大小的表;&nbsp;&nbsp;<BR>&nbsp;<BR>probe_loop:&nbsp;&nbsp;<BR>lodsb&nbsp;!!&nbsp;ds:si所指的字节&nbsp;=&gt;al,&nbsp;si=si+1;&nbsp;&nbsp;<BR>cbw&nbsp;!&nbsp;扩展为字(word);&nbsp;&nbsp;<BR>mov&nbsp;sectors,&nbsp;ax&nbsp;!&nbsp;第一个值是36,最后一个是9;&nbsp;&nbsp;<BR>cmp&nbsp;si,#disksizes+4&nbsp;&nbsp;<BR>jae&nbsp;got_sectors&nbsp;!&nbsp;如果所有测试都失败了,就试9;&nbsp;&nbsp;<BR>xchg&nbsp;ax,cx&nbsp;!&nbsp;cx&nbsp;=&nbsp;磁道和扇区(第一次是36=0x0024);&nbsp;&nbsp;<BR>xor&nbsp;dx,dx&nbsp;!&nbsp;驱动器0,磁头0;&nbsp;&nbsp;<BR>xor&nbsp;bl,bl&nbsp;!!&nbsp;设置缓冲区es:bx&nbsp;=&nbsp;0x9000:0x0a00(578.5k);&nbsp;&nbsp;<BR>mov&nbsp;bh,setup_sects&nbsp;!!&nbsp;setup_sects&nbsp;=&nbsp;4&nbsp;(共2k);&nbsp;&nbsp;<BR>inc&nbsp;bh&nbsp;&nbsp;<BR>shl&nbsp;bh,#1&nbsp;!&nbsp;setup后面的地址(es=cs);&nbsp;&nbsp;<BR>mov&nbsp;ax,#0x0201&nbsp;!&nbsp;功能2(读),1个扇区;&nbsp;&nbsp;<BR>int&nbsp;0x13&nbsp;&nbsp;<BR>jc&nbsp;probe_loop&nbsp;!&nbsp;如果不对,就试用下一个值;&nbsp;&nbsp;<BR>&nbsp;<BR>#endif&nbsp;&nbsp;<BR>&nbsp;<BR>got_sectors:&nbsp;&nbsp;<BR>&nbsp;<BR>!&nbsp;恢复es&nbsp;&nbsp;<BR>&nbsp;<BR>mov&nbsp;ax,#INITSEG&nbsp;&nbsp;<BR>mov&nbsp;es,ax&nbsp;!&nbsp;es&nbsp;=&nbsp;0x9000;&nbsp;&nbsp;<BR>&nbsp;<BR>!&nbsp;打印一些无用的信息(换行后,显示Loading)&nbsp;&nbsp;<BR>&nbsp;<BR>mov&nbsp;ah,#0x03&nbsp;!&nbsp;读光标位置;&nbsp;&nbsp;<BR>xor&nbsp;bh,bh&nbsp;&nbsp;<BR>int&nbsp;0x10&nbsp;&nbsp;<BR>&nbsp;<BR>mov&nbsp;cx,#9&nbsp;&nbsp;<BR>mov&nbsp;bx,#0x0007&nbsp;!&nbsp;页0,属性7&nbsp;(normal);&nbsp;&nbsp;<BR>mov&nbsp;bp,#msg1&nbsp;&nbsp;<BR>mov&nbsp;ax,#0x1301&nbsp;!&nbsp;写字符串,移动光标;&nbsp;&nbsp;<BR>int&nbsp;0x10&nbsp;&nbsp;<BR>&nbsp;<BR>!&nbsp;ok,&nbsp;我们已经显示出了信息,现在&nbsp;&nbsp;<BR>!&nbsp;我们要加载系统了(到0x10000处)(64k处)&nbsp;&nbsp;<BR>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -