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

📄 bootsect.s

📁 linux 0.11 内核源码。kernel-011-src.tar
💻 S
📖 第 1 页 / 共 2 页
字号:
! defined (!= 0), nothing is done and the given device is used.! Otherwise, either /dev/PS0 (2,28) or /dev/at0 (2,8), depending! on the number of sectors that the BIOS reports currently.! 此后,我们检查要使用哪个根文件系统设备(简称根设备)。如果已经指定了设备(!=0)! 就直接使用给定的设备。否则就需要根据BIOS 报告的每磁道扇区数来! 确定到底使用/dev/PS0 (2,28) 还是 /dev/at0 (2,8)。! 上面一行中两个设备文件的含义:! 在Linux 中软驱的主设备号是2(参见第43 行的注释),次设备号 = type*4 + nr,其中! nr 为0-3 分别对应软驱A、B、C 或D;type 是软驱的类型(2??1.2M 或7??1.44M 等)。! 因为7*4 + 0 = 28,所以 /dev/PS0 (2,28)指的是1.44M A 驱动器,其设备号是0x021c! 同理 /dev/at0 (2,8)指的是1.2M A 驱动器,其设备号是0x0208。seg csmov ax,root_dev ! 将根设备号cmp ax,#0jne root_definedseg csmov bx,sectors ! 取上面第88 行保存的每磁道扇区数。如果sectors=15! 则说明是1.2Mb 的驱动器;如果sectors=18,则说明是! 1.44Mb 软驱。因为是可引导的驱动器,所以肯定是A 驱。mov ax,#0x0208 ! /dev/ps0 - 1.2Mbcmp bx,#15 ! 判断每磁道扇区数是否=15je root_defined ! 如果等于,则ax 中就是引导驱动器的设备号。mov ax,#0x021c ! /dev/PS0 - 1.44Mbcmp bx,#18je root_definedundef_root: ! 如果都不一样,则死循环(死机)。jmp undef_rootroot_defined:seg csmov root_dev,ax ! 将检查过的设备号保存起来。! after that (everyting loaded), we jump to! the setup-routine loaded directly after! the bootblock:! 到此,所有程序都加载完毕,我们就跳转到被! 加载在bootsect 后面的setup 程序去。jmpi 0,SETUPSEG ! 跳转到0x9020:0000(setup.s 程序的开始处)。!!!! 本程序到此就结束了。!!!!! 下面是两个子程序。! This routine loads the system at address 0x10000, making sure! no 64kB boundaries are crossed. We try to load it as fast as! possible, loading whole tracks whenever we can.!! in: es - starting address segment (normally 0x1000)!! 该子程序将系统模块加载到内存地址0x10000 处,并确定没有跨越64KB 的内存边界。我们试图尽快! 地进行加载,只要可能,就每次加载整条磁道的数据。! 输入:es – 开始内存地址段值(通常是0x1000)sread: .word 1+SETUPLEN ! sectors read of current track! 当前磁道中已读的扇区数。开始时已经读进1 扇区的引导扇区! bootsect 和setup 程序所占的扇区数SETUPLEN。head: .word 0 ! current head !当前磁头号。track: .word 0 ! current track !当前磁道号。read_it:! 测试输入的段值。必须位于内存地址64KB 边界处,否则进入死循环。清bx 寄存器,用于表示当前段内! 存放数据的开始位置。mov ax,estest ax,#0x0fffdie: jne die ! es must be at 64kB boundary ! es 值必须位于64KB 地址边界!xor bx,bx ! bx is starting address within segment ! bx 为段内偏移位置。rp_read:! 判断是否已经读入全部数据。比较当前所读段是否就是系统数据末端所处的段(#ENDSEG),如果不是就! 跳转至下面ok1_read 标号处继续读数据。否则退出子程序返回。mov ax,escmp ax,#ENDSEG ! have we loaded all yet? ! 是否已经加载了全部数据?jb ok1_readretok1_read:! 计算和验证当前磁道需要读取的扇区数,放在ax 寄存器中。! 根据当前磁道还未读取的扇区数以及段内数据字节开始偏移位置,计算如果全部读取这些未读扇区,所! 读总字节数是否会超过64KB 段长度的限制。若会超过,则根据此次最多能读入的字节数(64KB – 段内! 偏移位置),反算出此次需要读取的扇区数。seg csmov ax,sectors ! 取每磁道扇区数。sub ax,sread ! 减去当前磁道已读扇区数。mov cx,ax ! cx = ax = 当前磁道未读扇区数。shl cx,#9 ! cx = cx * 512 字节。add cx,bx ! cx = cx + 段内当前偏移值(bx)! = 此次读操作后,段内共读入的字节数。jnc ok2_read ! 若没有超过64KB 字节,则跳转至ok2_read 处执行。je ok2_readxor ax,ax ! 若加上此次将读磁道上所有未读扇区时会超过64KB,则计算sub ax,bx ! 此时最多能读入的字节数(64KB – 段内读偏移位置),再转换shr ax,#9 ! 成需要读取的扇区数。ok2_read:call read_trackmov cx,ax ! cx = 该次操作已读取的扇区数。add ax,sread ! 当前磁道上已经读取的扇区数。seg cscmp ax,sectors ! 如果当前磁道上的还有扇区未读,则跳转到ok3_read 处。jne ok3_read! 读该磁道的下一磁头面(1 号磁头)上的数据。如果已经完成,则去读下一磁道。mov ax,#1sub ax,head ! 判断当前磁头号。jne ok4_read ! 如果是0 磁头,则再去读1 磁头面上的扇区数据。inc track ! 否则去读下一磁道。ok4_read:mov head,ax ! 保存当前磁头号。xor ax,ax ! 清当前磁道已读扇区数。ok3_read:mov sread,ax ! 保存当前磁道已读扇区数。shl cx,#9 ! 上次已读扇区数*512 字节。add bx,cx ! 调整当前段内数据开始位置。jnc rp_read ! 若小于64KB 边界值,则跳转到rp_read(156 行)处,继续读数据。! 否则调整当前段,为读下一段数据作准备。mov ax,esadd ax,#0x1000 ! 将段基址调整为指向下一个64KB 段内存。mov es,axxor bx,bx ! 清段内数据开始偏移值。jmp rp_read ! 跳转至rp_read(156 行)处,继续读数据。! 读当前磁道上指定开始扇区和需读扇区数的数据到es:bx 开始处。参见第67 行下对BIOS 磁盘读中断! int 0x13,ah=2 的说明。! al – 需读扇区数;es:bx – 缓冲区开始位置。read_track:push axpush bxpush cxpush dxmov dx,track ! 取当前磁道号。mov cx,sread ! 取当前磁道上已读扇区数。inc cx ! cl = 开始读扇区。mov ch,dl ! ch = 当前磁道号。mov dx,head ! 取当前磁头号。mov dh,dl ! dh = 磁头号。mov dl,#0 ! dl = 驱动器号(为0 表示当前驱动器)。and dx,#0x0100 ! 磁头号不大于1。mov ah,#2 ! ah = 2,读磁盘扇区功能号。int 0x13jc bad_rt ! 若出错,则跳转至bad_rt。pop dxpop cxpop bxpop axret! 执行驱动器复位操作(磁盘中断功能号0),再跳转到read_track 处重试。bad_rt: mov ax,#0mov dx,#0int 0x13pop dxpop cxpop bxpop axjmp read_track/** This procedure turns off the floppy drive motor, so* that we enter the kernel in a known state, and* don't have to worry about it later.*/! 这个子程序用于关闭软驱的马达,这样我们进入内核后它处于已知状态,以后也就无须担心它了。kill_motor:push dxmov dx,#0x3f2 ! 软驱控制卡的驱动端口,只写。mov al,#0 ! A 驱动器,关闭FDC,禁止DMA 和中断请求,关闭马达。outb ! 将al 中的内容输出到dx 指定的端口去。pop dxretsectors:.word 0 ! 存放当前启动软盘每磁道的扇区数。msg1:.byte 13,10 ! 回车、换行的ASCII 码。.ascii "Loading system ...".byte 13,10,13,10 ! 共24 个ASCII 码字符。.org 508 ! 表示下面语句从地址508(0x1FC)开始,所以root_dev! 在启动扇区的第508 开始的2 个字节中。root_dev:.word ROOT_DEV ! 这里存放根文件系统所在的设备号(init/main.c 中会用)。boot_flag:.word 0xAA55 ! 硬盘有效标识。.textendtext:.dataenddata:.bssendbss:

⌨️ 快捷键说明

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