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

📄 00000050.htm

📁 一份很好的linux入门资料
💻 HTM
📖 第 1 页 / 共 2 页
字号:
&nbsp;<BR>mov&nbsp;ax,#SYSSEG&nbsp;&nbsp;<BR>mov&nbsp;es,ax&nbsp;!&nbsp;es=0x01000的段;&nbsp;&nbsp;<BR>call&nbsp;read_it&nbsp;!!&nbsp;读system,es为输入参数;&nbsp;&nbsp;<BR>call&nbsp;kill_motor&nbsp;!!&nbsp;关闭驱动器马达;&nbsp;&nbsp;<BR>call&nbsp;print_nl&nbsp;!!&nbsp;打印回车换行;&nbsp;&nbsp;<BR>&nbsp;<BR>!&nbsp;这以后,我们来检查要使用哪个根设备(root-device)。如果已指定了设备(!=0)&nbsp;&nbsp;<BR>!&nbsp;则不做任何事而使用给定的设备。否则的话,使用/dev/fd0H2880&nbsp;(2,32)或/dev/PS0&nbsp;&nbsp;<BR>(2,28)&nbsp;&nbsp;<BR>!&nbsp;或者是/dev/at0&nbsp;(2,8)之一,这取决于我们假设我们知道的扇区数而定。&nbsp;&nbsp;<BR>!!&nbsp;|__&nbsp;ps0??&nbsp;(x,y)--表示主、次设备号?&nbsp;&nbsp;<BR>&nbsp;<BR>seg&nbsp;cs&nbsp;&nbsp;<BR>mov&nbsp;ax,root_dev&nbsp;&nbsp;<BR>or&nbsp;ax,ax&nbsp;&nbsp;<BR>jne&nbsp;root_defined&nbsp;&nbsp;<BR>seg&nbsp;cs&nbsp;&nbsp;<BR>mov&nbsp;bx,sectors&nbsp;!!&nbsp;sectors&nbsp;=&nbsp;每磁道扇区数;&nbsp;&nbsp;<BR>mov&nbsp;ax,#0x0208&nbsp;!&nbsp;/dev/ps0&nbsp;-&nbsp;1.2Mb;&nbsp;&nbsp;<BR>cmp&nbsp;bx,#15&nbsp;&nbsp;<BR>je&nbsp;root_defined&nbsp;&nbsp;<BR>mov&nbsp;al,#0x1c&nbsp;!&nbsp;/dev/PS0&nbsp;-&nbsp;1.44Mb&nbsp;!!&nbsp;0x1C&nbsp;=&nbsp;28;&nbsp;&nbsp;<BR>cmp&nbsp;bx,#18&nbsp;&nbsp;<BR>je&nbsp;root_defined&nbsp;&nbsp;<BR>mov&nbsp;al,0x20&nbsp;!&nbsp;/dev/fd0H2880&nbsp;-&nbsp;2.88Mb;&nbsp;&nbsp;<BR>cmp&nbsp;bx,#36&nbsp;&nbsp;<BR>je&nbsp;root_defined&nbsp;&nbsp;<BR>mov&nbsp;al,#0&nbsp;!&nbsp;/dev/fd0&nbsp;-&nbsp;autodetect;&nbsp;&nbsp;<BR>root_defined:&nbsp;&nbsp;<BR>seg&nbsp;cs&nbsp;&nbsp;<BR>mov&nbsp;root_dev,ax&nbsp;!!&nbsp;其中保存由设备的主、次设备号;&nbsp;&nbsp;<BR>&nbsp;<BR>!&nbsp;这以后(所有程序都加载了),我们就跳转至&nbsp;&nbsp;<BR>!&nbsp;被直接加载到boot块后面的setup程序去:&nbsp;&nbsp;<BR>&nbsp;<BR>jmpi&nbsp;0,SETUPSEG&nbsp;!!&nbsp;跳转到0x9020:0000(setup程序的开始位置);&nbsp;&nbsp;<BR>&nbsp;<BR>&nbsp;<BR>!&nbsp;这段程序将系统(system)加载到0x10000(64k)处,&nbsp;&nbsp;<BR>!&nbsp;注意不要跨越64kb边界。我们试图以最快的速度&nbsp;&nbsp;<BR>!&nbsp;来加载,只要可能就整个磁道一起读入。&nbsp;&nbsp;<BR>!&nbsp;&nbsp;<BR>!&nbsp;输入(in):&nbsp;es&nbsp;-&nbsp;开始地址段(通常是0x1000)&nbsp;&nbsp;<BR>!&nbsp;&nbsp;<BR>sread:&nbsp;.word&nbsp;0&nbsp;!&nbsp;当前磁道已读的扇区数;&nbsp;&nbsp;<BR>head:&nbsp;.word&nbsp;0&nbsp;!&nbsp;当前磁头;&nbsp;&nbsp;<BR>track:&nbsp;.word&nbsp;0&nbsp;!&nbsp;当前磁道;&nbsp;&nbsp;<BR>&nbsp;<BR>read_it:&nbsp;&nbsp;<BR>mov&nbsp;al,setup_sects&nbsp;&nbsp;<BR>inc&nbsp;al&nbsp;&nbsp;<BR>mov&nbsp;sread,al&nbsp;!!&nbsp;当前sread=5;&nbsp;&nbsp;<BR>mov&nbsp;ax,es&nbsp;!!&nbsp;es=0x1000;&nbsp;&nbsp;<BR>test&nbsp;ax,#0x0fff&nbsp;!!&nbsp;(ax&nbsp;AND&nbsp;0x0fff,&nbsp;if&nbsp;ax=0x1000&nbsp;then&nbsp;zero-flag=1&nbsp;);&nbsp;&nbsp;<BR>die:&nbsp;jne&nbsp;die&nbsp;!&nbsp;es&nbsp;必须在64kB的边界;&nbsp;&nbsp;<BR>xor&nbsp;bx,bx&nbsp;!&nbsp;bx&nbsp;是段内的开始地址;&nbsp;&nbsp;<BR>rp_read:&nbsp;&nbsp;<BR>#ifdef&nbsp;__BIG_KERNEL__&nbsp;&nbsp;<BR>#define&nbsp;CALL_HIGHLOAD_KLUDGE&nbsp;.word&nbsp;0x1eff,&nbsp;0x220&nbsp;!&nbsp;调用&nbsp;far&nbsp;*&nbsp;bootsect_kludge&nbsp;&nbsp;<BR>!&nbsp;注意:&nbsp;as86不能汇编这;&nbsp;&nbsp;<BR>CALL_HIGHLOAD_KLUDGE&nbsp;!&nbsp;这是在setup.S中的程序;&nbsp;&nbsp;<BR>#else&nbsp;&nbsp;<BR>mov&nbsp;ax,es&nbsp;&nbsp;<BR>sub&nbsp;ax,#SYSSEG&nbsp;!&nbsp;当前es段值减system加载时的启始段值(0x1000);&nbsp;&nbsp;<BR>#endif&nbsp;&nbsp;<BR>cmp&nbsp;ax,syssize&nbsp;!&nbsp;我们是否已经都加载了?(ax=0x7f00&nbsp;?);&nbsp;&nbsp;<BR>jbe&nbsp;ok1_read&nbsp;!!&nbsp;if&nbsp;ax&nbsp;&lt;=&nbsp;syssize&nbsp;then&nbsp;继续读;&nbsp;&nbsp;<BR>ret&nbsp;!!&nbsp;全都加载完了,返回!&nbsp;&nbsp;<BR>ok1_read:&nbsp;&nbsp;<BR>mov&nbsp;ax,sectors&nbsp;!!&nbsp;sectors=每磁道扇区数;&nbsp;&nbsp;<BR>sub&nbsp;ax,sread&nbsp;!!&nbsp;减去当前磁道已读扇区数,al=当前磁道未读的扇区数(ah=0);&nbsp;&nbsp;<BR>mov&nbsp;cx,ax&nbsp;&nbsp;<BR>shl&nbsp;cx,#9&nbsp;!!&nbsp;乘512,cx&nbsp;=&nbsp;当前磁道未读的字节数;&nbsp;&nbsp;<BR>add&nbsp;cx,bx&nbsp;!!&nbsp;加上段内偏移值,es:bx为当前读入的数据缓冲区地址;&nbsp;&nbsp;<BR>jnc&nbsp;ok2_read&nbsp;!!&nbsp;如果没有超过64K则继续读;&nbsp;&nbsp;<BR>je&nbsp;ok2_read&nbsp;!!&nbsp;如果正好64K也继续读;&nbsp;&nbsp;<BR>xor&nbsp;ax,ax&nbsp;&nbsp;<BR>sub&nbsp;ax,bx&nbsp;&nbsp;<BR>shr&nbsp;ax,#9&nbsp;&nbsp;<BR>ok2_read:&nbsp;&nbsp;<BR>call&nbsp;read_track&nbsp;!!&nbsp;es:bx&nbsp;-&gt;缓冲区,al=要读的扇区数,也即当前磁道未读的扇区数;&nbsp;<BR>&nbsp;&nbsp;<BR>mov&nbsp;cx,ax&nbsp;!!&nbsp;ax仍为调用read_track之前的值,即为读入的扇区数;&nbsp;&nbsp;<BR>add&nbsp;ax,sread&nbsp;!!&nbsp;ax&nbsp;=&nbsp;当前磁道已读的扇区数;&nbsp;&nbsp;<BR>cmp&nbsp;ax,sectors&nbsp;!!&nbsp;已经读完当前磁道上的扇区了吗?&nbsp;&nbsp;<BR>jne&nbsp;ok3_read&nbsp;!!&nbsp;没有,则跳转;&nbsp;&nbsp;<BR>mov&nbsp;ax,#1&nbsp;&nbsp;<BR>sub&nbsp;ax,head&nbsp;!!&nbsp;当前是磁头1吗?&nbsp;&nbsp;<BR>jne&nbsp;ok4_read&nbsp;!!&nbsp;不是(是磁头0)则跳转(此时ax=1);&nbsp;&nbsp;<BR>inc&nbsp;track&nbsp;!!&nbsp;当前是磁头1,则读下一磁道(当前磁道加1);&nbsp;&nbsp;<BR>ok4_read:&nbsp;&nbsp;<BR>mov&nbsp;head,ax&nbsp;!!&nbsp;保存当前磁头号;&nbsp;&nbsp;<BR>xor&nbsp;ax,ax&nbsp;!!&nbsp;本磁道已读扇区数清零;&nbsp;&nbsp;<BR>ok3_read:&nbsp;&nbsp;<BR>mov&nbsp;sread,ax&nbsp;!!&nbsp;存本磁道已读扇区数;&nbsp;&nbsp;<BR>shl&nbsp;cx,#9&nbsp;!!&nbsp;刚才一次读操作读入的扇区数&nbsp;*&nbsp;512;&nbsp;&nbsp;<BR>add&nbsp;bx,cx&nbsp;!!&nbsp;调整数据缓冲区的起始指针;&nbsp;&nbsp;<BR>jnc&nbsp;rp_read&nbsp;!!&nbsp;如果该指针没有超过64K的段内最大偏移量,则跳转继续读操作;&nbsp;&nbsp;<BR>mov&nbsp;ax,es&nbsp;!!&nbsp;如果超过了,则将段地址加0x1000(下一个64K段);&nbsp;&nbsp;<BR>add&nbsp;ah,#0x10&nbsp;&nbsp;<BR>mov&nbsp;es,ax&nbsp;&nbsp;<BR>xor&nbsp;bx,bx&nbsp;!!&nbsp;缓冲区地址段内偏移量置零;&nbsp;&nbsp;<BR>jmp&nbsp;rp_read&nbsp;!!&nbsp;继续读操作;&nbsp;&nbsp;<BR>&nbsp;<BR>&nbsp;<BR>&nbsp;<BR>read_track:&nbsp;&nbsp;<BR>pusha&nbsp;!!&nbsp;将寄存器ax,cx,dx,bx,sp,bp,si,di压入堆栈;&nbsp;&nbsp;<BR>pusha&nbsp;&nbsp;<BR>mov&nbsp;ax,#0xe2e&nbsp;!&nbsp;loading...&nbsp;message&nbsp;2e&nbsp;=&nbsp;.&nbsp;!!&nbsp;显示一个.&nbsp;&nbsp;<BR>mov&nbsp;bx,#7&nbsp;&nbsp;<BR>int&nbsp;0x10&nbsp;&nbsp;<BR>popa&nbsp;&nbsp;<BR>&nbsp;<BR>mov&nbsp;dx,track&nbsp;!!&nbsp;track&nbsp;=&nbsp;当前磁道;&nbsp;&nbsp;<BR>mov&nbsp;cx,sread&nbsp;&nbsp;<BR>inc&nbsp;cx&nbsp;!!&nbsp;cl&nbsp;=&nbsp;扇区号,要读的起始扇区;&nbsp;&nbsp;<BR>mov&nbsp;ch,dl&nbsp;!!&nbsp;ch&nbsp;=&nbsp;磁道号的低8位;&nbsp;&nbsp;<BR>mov&nbsp;dx,head&nbsp;!!&nbsp;&nbsp;<BR>mov&nbsp;dh,dl&nbsp;!!&nbsp;dh&nbsp;=&nbsp;当前磁头号;&nbsp;&nbsp;<BR>and&nbsp;dx,#0x0100&nbsp;!!&nbsp;dl&nbsp;=&nbsp;驱动器号(0);&nbsp;&nbsp;<BR>mov&nbsp;ah,#2&nbsp;!!&nbsp;功能2(读),es:bx指向读数据缓冲区;&nbsp;&nbsp;<BR>&nbsp;<BR>push&nbsp;dx&nbsp;!&nbsp;为出错转储保存寄存器的值到堆栈上;&nbsp;&nbsp;<BR>push&nbsp;cx&nbsp;&nbsp;<BR>push&nbsp;bx&nbsp;&nbsp;<BR>push&nbsp;ax&nbsp;&nbsp;<BR>&nbsp;<BR>int&nbsp;0x13&nbsp;&nbsp;<BR>jc&nbsp;bad_rt&nbsp;!!&nbsp;如果出错,则跳转;&nbsp;&nbsp;<BR>add&nbsp;sp,&nbsp;#8&nbsp;!!&nbsp;清(放弃)堆栈上刚推入的4个寄存器值;&nbsp;&nbsp;<BR>popa&nbsp;&nbsp;<BR>ret&nbsp;&nbsp;<BR>&nbsp;<BR>bad_rt:&nbsp;push&nbsp;ax&nbsp;!&nbsp;保存出错码;&nbsp;&nbsp;<BR>call&nbsp;print_all&nbsp;!&nbsp;ah&nbsp;=&nbsp;error,&nbsp;al&nbsp;=&nbsp;read;&nbsp;&nbsp;<BR>&nbsp;<BR>&nbsp;<BR>xor&nbsp;ah,ah&nbsp;&nbsp;<BR>xor&nbsp;dl,dl&nbsp;&nbsp;<BR>int&nbsp;0x13&nbsp;&nbsp;<BR>&nbsp;<BR>&nbsp;<BR>add&nbsp;sp,#10&nbsp;&nbsp;<BR>popa&nbsp;&nbsp;<BR>jmp&nbsp;read_track&nbsp;&nbsp;<BR>&nbsp;<BR>/*&nbsp;&nbsp;<BR>*&nbsp;print_all是用于调试的。&nbsp;&nbsp;<BR>*&nbsp;它将打印出所有寄存器的值。所作的假设是&nbsp;&nbsp;<BR>*&nbsp;从一个子程序中调用的,并有如下所示的堆栈帧结构&nbsp;&nbsp;<BR>*&nbsp;dx&nbsp;&nbsp;<BR>*&nbsp;cx&nbsp;&nbsp;<BR>*&nbsp;bx&nbsp;&nbsp;<BR>*&nbsp;ax&nbsp;&nbsp;<BR>*&nbsp;error&nbsp;&nbsp;<BR>*&nbsp;ret&nbsp;&lt;-&nbsp;sp&nbsp;&nbsp;<BR>*&nbsp;&nbsp;<BR>*/&nbsp;&nbsp;<BR>&nbsp;<BR>print_all:&nbsp;&nbsp;<BR>mov&nbsp;cx,#5&nbsp;!&nbsp;出错码&nbsp;+&nbsp;4个寄存器&nbsp;&nbsp;<BR>mov&nbsp;bp,sp&nbsp;&nbsp;<BR>&nbsp;<BR>print_loop:&nbsp;&nbsp;<BR>push&nbsp;cx&nbsp;!&nbsp;保存剩余的计数值&nbsp;&nbsp;<BR>call&nbsp;print_nl&nbsp;!&nbsp;为了增强阅读性,打印换行&nbsp;&nbsp;<BR>&nbsp;<BR>cmp&nbsp;cl,&nbsp;#5&nbsp;&nbsp;<BR>jae&nbsp;no_reg&nbsp;!&nbsp;看看是否需要寄存器的名称&nbsp;&nbsp;<BR>&nbsp;<BR>mov&nbsp;ax,#0xe05&nbsp;+&nbsp;A&nbsp;-&nbsp;l&nbsp;&nbsp;<BR>sub&nbsp;al,cl&nbsp;&nbsp;<BR>int&nbsp;0x10&nbsp;&nbsp;<BR>&nbsp;<BR>mov&nbsp;al,#X&nbsp;&nbsp;<BR>int&nbsp;0x10&nbsp;&nbsp;<BR>&nbsp;<BR>mov&nbsp;al,#:&nbsp;&nbsp;<BR>int&nbsp;0x10&nbsp;&nbsp;<BR>&nbsp;<BR>no_reg:&nbsp;&nbsp;<BR>add&nbsp;bp,#2&nbsp;!&nbsp;下一个寄存器&nbsp;&nbsp;<BR>call&nbsp;print_hex&nbsp;!&nbsp;打印值&nbsp;&nbsp;<BR>pop&nbsp;cx&nbsp;&nbsp;<BR>loop&nbsp;print_loop&nbsp;&nbsp;<BR>ret&nbsp;&nbsp;<BR>&nbsp;<BR>print_nl:&nbsp;!!&nbsp;打印回车换行。&nbsp;&nbsp;<BR>mov&nbsp;ax,#0xe0d&nbsp;!&nbsp;CR&nbsp;&nbsp;<BR>int&nbsp;0x10&nbsp;&nbsp;<BR>mov&nbsp;al,#0xa&nbsp;!&nbsp;LF&nbsp;&nbsp;<BR>int&nbsp;0x10&nbsp;&nbsp;<BR>ret&nbsp;&nbsp;<BR>&nbsp;<BR>/*&nbsp;&nbsp;<BR>*&nbsp;print_hex是用于调试目的的,打印出&nbsp;&nbsp;<BR>*&nbsp;ss:bp所指向的十六进制数。&nbsp;&nbsp;<BR>*&nbsp;!!&nbsp;例如,十六进制数是0x4321时,则al分别等于4,3,2,1调用中断打印出来&nbsp;4321&nbsp;&nbsp;<BR>*/&nbsp;&nbsp;<BR>&nbsp;<BR>print_hex:&nbsp;&nbsp;<BR>mov&nbsp;cx,&nbsp;#4&nbsp;!&nbsp;4个十六进制数字&nbsp;&nbsp;<BR>mov&nbsp;dx,&nbsp;(bp)&nbsp;!&nbsp;将(bp)所指的值放入dx中&nbsp;&nbsp;<BR>print_digit:&nbsp;&nbsp;<BR>rol&nbsp;dx,&nbsp;#4&nbsp;!&nbsp;循环以使低4比特用上&nbsp;!!&nbsp;取dx的高4比特移到低4比特处。&nbsp;&nbsp;<BR>mov&nbsp;ax,&nbsp;#0xe0f&nbsp;!&nbsp;ah&nbsp;=&nbsp;请求的功能值,al&nbsp;=&nbsp;半字节(4个比特)掩码。&nbsp;&nbsp;<BR>and&nbsp;al,&nbsp;dl&nbsp;!!&nbsp;取dl的低4比特值。&nbsp;&nbsp;<BR>add&nbsp;al,&nbsp;#0x90&nbsp;!&nbsp;将al转换为ASCII十六进制码(4个指令)&nbsp;&nbsp;<BR>daa&nbsp;!!&nbsp;十进制调整&nbsp;&nbsp;<BR>adc&nbsp;al,&nbsp;#0x40&nbsp;!!&nbsp;(adc&nbsp;dest,&nbsp;src&nbsp;==&gt;&nbsp;dest&nbsp;:=&nbsp;dest&nbsp;+&nbsp;src&nbsp;+&nbsp;c&nbsp;)&nbsp;&nbsp;<BR>daa&nbsp;&nbsp;<BR>int&nbsp;0x10&nbsp;&nbsp;<BR>loop&nbsp;print_digit&nbsp;&nbsp;<BR>ret&nbsp;&nbsp;<BR>&nbsp;<BR>&nbsp;<BR>/*&nbsp;&nbsp;<BR>*&nbsp;这个过程(子程序)关闭软驱的马达,这样&nbsp;&nbsp;<BR>*&nbsp;我们进入内核后它的状态就是已知的,以后也就&nbsp;&nbsp;<BR>*&nbsp;不用担心它了。&nbsp;&nbsp;<BR>*/&nbsp;&nbsp;<BR>kill_motor:&nbsp;&nbsp;<BR>push&nbsp;dx&nbsp;&nbsp;<BR>mov&nbsp;dx,#0x3f2&nbsp;&nbsp;<BR>xor&nbsp;al,al&nbsp;&nbsp;<BR>outb&nbsp;&nbsp;<BR>pop&nbsp;dx&nbsp;&nbsp;<BR>ret&nbsp;&nbsp;<BR>&nbsp;<BR>!!&nbsp;数据区&nbsp;&nbsp;<BR>sectors:&nbsp;&nbsp;<BR>.word&nbsp;0&nbsp;!!&nbsp;当前每磁道扇区数。(36||18||15||9)&nbsp;&nbsp;<BR>&nbsp;<BR>disksizes:&nbsp;!!&nbsp;每磁道扇区数表&nbsp;&nbsp;<BR>.byte&nbsp;36,&nbsp;18,&nbsp;15,&nbsp;9&nbsp;&nbsp;<BR>&nbsp;<BR>msg1:&nbsp;&nbsp;<BR>.byte&nbsp;13,&nbsp;10&nbsp;&nbsp;<BR>.ascii&nbsp;&quot;Loading&quot;&nbsp;&nbsp;<BR>&nbsp;<BR>.org&nbsp;497&nbsp;!!&nbsp;从boot程序的二进制文件的497字节开始&nbsp;&nbsp;<BR>setup_sects:&nbsp;&nbsp;<BR>.byte&nbsp;SETUPSECS&nbsp;&nbsp;<BR>root_flags:&nbsp;&nbsp;<BR>.word&nbsp;CONFIG_ROOT_RDONLY&nbsp;&nbsp;<BR>syssize:&nbsp;&nbsp;<BR>.word&nbsp;SYSSIZE&nbsp;&nbsp;<BR>swap_dev:&nbsp;&nbsp;<BR>.word&nbsp;SWAP_DEV&nbsp;&nbsp;<BR>ram_size:&nbsp;&nbsp;<BR>.word&nbsp;RAMDISK&nbsp;&nbsp;<BR>vid_mode:&nbsp;&nbsp;<BR>.word&nbsp;SVGA_MODE&nbsp;&nbsp;<BR>root_dev:&nbsp;&nbsp;<BR>.word&nbsp;ROOT_DEV&nbsp;&nbsp;<BR>boot_flag:&nbsp;!!&nbsp;分区启动标志&nbsp;&nbsp;<BR>.word&nbsp;0xAA55&nbsp;&nbsp;<BR>&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;<BR>&nbsp;<BR>来源:Linux自由鸽&nbsp;&nbsp;&nbsp;<BR>&nbsp;<BR>--&nbsp;<BR>&nbsp;<BR>※&nbsp;来源:·BBS&nbsp;水木清华站&nbsp;smth.org·[FROM:&nbsp;159.226.41.166]&nbsp;<BR><CENTER><H1>BBS水木清华站∶精华区</H1></CENTER></BODY></HTML>

⌨️ 快捷键说明

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