东北大学 bootblock-只有汉语注释.doc_第1页
东北大学 bootblock-只有汉语注释.doc_第2页
东北大学 bootblock-只有汉语注释.doc_第3页
东北大学 bootblock-只有汉语注释.doc_第4页
东北大学 bootblock-只有汉语注释.doc_第5页
已阅读5页,还剩4页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

2000 ! Bootblock 1.4 - Minix boot block. Author: Kees J. Bot 2001 ! 21 Dec 1991 20022016 ! 1. 功能描述:当PC加电后,PC试图读软盘0的第一扇区到0x7C00。如果因为没有可用的磁介质而失败,则它试图从硬盘的第一个扇区读主引导记录(master boot record),该扇区不仅包含可执行代码,也包含硬盘的分区表(DPT,disk partition table)。当他执行时,他将选择活动分区并把他的第一个扇区到0x7C00。本文件包含最终从软盘或从硬盘分区读出的代码,它将从引导设备上加载次级引导代码到内存地址0x10000处,并执行他。次级引导代码在磁盘上的地址是由installboot将24位的扇区号和8位的扇区数(above enddata upwards)。次级引导代码也足够聪明,能够将MINIX内核的不同部分加载到内存,并执行他们直到最后使Minix启动。2017 ! 入口参数:(1)dl寄存器包含用于启动的驱动器(即,本文件的代码来自于该驱动器)。对于第一、第二软驱值是0x00和0x01,对于硬驱是0x80, 0x81, 0x82, or 0x83。(2)如果本代码来自于硬盘,并是主引导记录装载该代码,则对应于引导分区的分区表入口是由es:si传递。2018 2019LOADOFF=0x7C00 ! 0x0000:LOADOFF is where this code is loaded 2020 BOOTSEG=0x1000 ! Secondary boot code segment. 2021 BOOTOFF=0x0030 ! Offset into secondary boot above header 2022 BUFFER =0x0600 ! First free memory 2023 LOWSEC = 8 ! Offset of logical first sector in partition 2024 ! table 2025 2026 ! Variables addressed using bp register 2027 device = 0 ! The boot device 2028 lowsec = 2 ! Offset of boot partition within drive 2029 secpcyl= 6 ! Sectors per cylinder = heads * sectors 这在汇编中是相当普遍的事。将几个值压入堆栈(lines 2043, 2044, and 2046),并且堆栈指针sp保存在bp中(mov bp, sp - line 2047)。如果2字节值压入堆栈,那么最后的两字节通过0(bp)存取,之后的两字节使用2(bp)存取,等等(见line 2095)。这里有3个变量占用8字节,仅有6字节压入堆栈。lowsec (lines 2043 and 2044) and device (line 2046) 被压入堆栈,但是secpcyl变量如何? 当最后一个值存储到secpcyl变量中 (line 2110),bootblock代码的头两个字节被覆盖即第一条指令xor ax, ax instruction (line 2036)被覆盖。这没有关系因为代码再不会跳到开头执行。这个存储不仅是变量需要的2字节,还有push指令需要的存储器。2030 2031 .text 2032 2033 ! Start boot procedure. 2034 2035 boot: 2036 xor ax, ax ! ax = 0x0000, the vector segment 2037 mov ds, ax 第一条指令(xor ax, ax)使AX清0。它比mov ax, #0快。指令中操作符的顺序:mov destination, source/* 设置堆栈,在0:LOADOFF(0:0x7c00)处; 栈底在0:0x7c00处2038 cli ! Ignore interrupts while setting stack 2039 mov ss, ax ! ss = ds = vector segment2040 mov sp, #LOADOFF ! Usual place for a bootstrap stack 2041 sti 当修改ss和sp的值时,必须首先屏蔽中断。堆栈保留着中断完成后返回地址。如果ss和sp寄存器在改变中,并且此时发生中断,则不能预测代码将返回到何处。Cli关中断,sti开中断。#LOADOFF前的(pound)号表示是将LOADOFF的值(0x7C00 - see line 2019)装入,而不是LOADOFF处的内存值。2042 2043 push ax 2044 push ax ! Push a zero lowsec(bp) 2045 2046 push dx ! Boot device in dl will be device(bp) 2047 mov bp, sp ! Using var(bp) is one byte cheaper then var.这里使用了一点技巧。但是想法是:一条立即数指令比一条指定地址模式指令(ss:dispbp)多一个字节。例如,line 2095的指令(mov es, lowsec(bp))比指令mov es, LOADOFF+lowsec少一个字节。因为boorlock代码和扇区地址((see lines 2204-2206))必须放在一个块中(1 block = 2 sectors = 2 * 512 bytes = 1024 bytes),应该节约空间因为堆栈不占用硬盘空间,硬盘空间通过不在代码中分配空间而节省(使用.data1 or .data2)2048 2049 push es 2050 push si ! es:si = partition table entry if hard disk 如果是硬盘,则es:si是分区表的入口2051 2052 mov di, #LOADOFF+sectors ! char *di = sectors; , 指向每磁道的扇区数/* sectors 是L2200行定义的一个Labledi now points to sectors (line 2200). 2053 2054 testb dl, dl ! Winchester disks if dl = 0x80 2055 jge floppy如果dl中的值是负值,则Testb设置符号位。如果不是负数,jge跳到floppy。记住:0x00 and 0x01对应头两个软盘,0x80, 0x81, 0x82, and 0x83对应14个硬盘。2056 2057 winchester: 2058 2059 ! Get the offset of the first sector of the boot partition from the partition 2060 ! table. The table is found at es:si, the lowsec parameter at offset LOWSEC. 2061 从分区表获得引导分区的第一个扇区的偏移量。由es:si得到分区表,lowsec参数在LOWSEC处2062 eseg !指令前的eseg表示,使用es作为段寄存器2063 les ax, LOWSEC(si) ! es:ax = LOWSEC+2(si):LOWSEC(si)2064 mov lowsec+0(bp), ax ! Low 16 bits of partitions first sector2065 mov lowsec+2(bp), es ! High 16 bits of partitions first sector 指令前的eseg表示,使用es作为段寄存器。Les指令将源操作数指向值的低16位(es:LOWSEC(si))装入ax寄存器,将高16位值(es:LOWSEC+2(si)装入 es。注意:es:ax的值由 eseg les ax, LOWSEC(si) 重新复制。因此,es和ax的值在lines 2049-2050.被压入堆栈。?2066 2067 ! Get the drive parameters, the number of sectors is bluntly written into the 2068 ! floppy disk sectors/track array. 2069 获得驱动器参数,扇区数被直接写入软盘扇区或/ 磁道阵列2070 movb ah, #0x08 ! Code for drive parameters 驱动参数代码2071 int 0x13 ! dl still contains drive 指令int 0x13, ah=0x08返回由dl指定的驱动器几何参数。对于硬盘dl0x800x82。int 0x13, ah=0x08返回最大扇区号在cl的06位中,在dh中最大头号(最大扇区头号从0开始)。在2074行将dh值加一,使之从1开始计数。2072 andb cl, #0x3F ! cl = max sector number (1-origin) 2073 movb (di), cl ! Number of sectors per track 每磁道的扇区数存于sector处2074 incb dh ! dh = 1 + max head number (0-origin) 2075 jmp loadboot 2076 2077 ! Floppy: 首先试图读软盘上的第18号扇区。如果失败,则dl中指定的驱动器不是一个1.44M软驱。则试图读软盘的第一道的第15扇区。如果失败,dl指定的驱动器不是1.2的软驱。最后试图读第9扇区(对于360/720软盘)。2082 2083 next: inc di ! Next number of sectors per track di points to sectors (see lines 2052 and 2200). 2084 2085 floppy: xorb ah, ah ! Reset drive int 0x13, ah=0x00 resets the drive specified by dl. 重置由dl指定的驱动器2086 int 0x13 2087 2088 movb cl, (di) ! cl = number of last sector on track 2089 2090 cmpb cl, #9 ! No need to do the last 720K/360K test 2091 je success 2092 2093 ! Try to read the last sector on track 0 试图读一个磁道上的最后一个扇区2094 2095 mov es, lowsec(bp) ! es = vector segment (lowsec = 0) 2096 mov bx, #BUFFER ! es:bx buffer = 0x0000:0x0600 内存中从BUFFER开始的区域到目前位置还没有使用过,因此该区域可用做缓冲区,硬盘的扇区数可以复制到那里,以便测试软驱。2097 mov ax, #0x0201 ! Read sector, #sectors = 1 2098 xorb ch, ch ! Track 0, last sector 2099 xorb dh, dh ! Drive dl, head 0 2100 int 0x13 int 0x13, ah=0x02读扇区从软盘或硬盘。Al指定读取的扇区数,cl的05位指定扇区号,dh指定头号,ch指定柱面号的低8位,cl的67位指定柱面号的高两位。Es:bx指定内存地址。如果int 0x13, ah=0x02指令失败,carry (C) 表示置位。如果C标志置位,jc指令跳转到next2101 jc next ! Error, try the next floppy type 2102 2103success: movb dh, #2 ! Load number of heads for multiply A floppy is a single disk with 2 heads, one for each side. 2104 2105 loadboot: Lines 2105-2153是Lines 2105-2153的核心。在内存地址address处(line 2204)列出的扇区被加载;这些扇区构成了次级引导。扇区数由installboot utility program填补到该地址。2106 ! Load the secondary boot code from the boot device 从引导设备上加载次级引导代码2107 2108 movb al, (di) ! al = (di) = sectors per track 2109 mulb dh ! dh = heads, ax = heads * sectors mulb multiplies al by the operand (in this case dh). The result is placed in ax. 2110 mov secpcyl(bp), ax ! Sectors per cylinder = heads * sectors 2111 2112 mov ax, #BOOTSEG ! Segment to load secondary boot code into 2113 mov es, ax 2114 xor bx, bx ! Load first sector at es:bx = BOOTSEG:0x0000 2115 mov si, #LOADOFF+addresses ! Start of the boot code addresses 2116 load: 2117 mov ax, 1(si) ! Get next sector number: low 16 bits 2118 movb dl, 3(si) ! Bits 16-23 for your 8GB disk2119 xorb dh, dh ! dx:ax = sector within partitionInstallboot使用程序在地址address处填补2个值具有4个字节的表项。第一字节用于计数(count),第2,3,4字节用于扇区号(实际上是一个分区内的扇区偏移见2120-2121的说明)。描述计数(count)的最好方法是在例子中。如果次级引导代码在扇区500, 501, 502, 509, and 510,则在address处由两个表项:第一表项是count3,扇区号500;第二个表项是count2,扇区号是509。2120 add ax, lowsec+0(bp) 2121 adc dx, lowsec+2(bp) ! dx:ax = sector within drive 在address处填补的值是一个分区内的扇区偏移量,而不是绝对扇区号。int 0x13, ah=0x02指令需要绝对扇区号,所以lowsec被加到了偏移中(lowsec是该扇区的第一个扇区)2122 div secpcyl(bp) ! ax = cylinder, dx = sector within cylinder 2123 xchg ax, dx ! ax = sector within cylinder, dx = cylinder 2124 movb ch, dl ! ch = low 8 bits of cylinder 2125 divb (di) ! al = head, ah = sector (0-origin) Divb指令使用操作数(di)除以ax。Di指向的内存单元包含有每道的扇区数, 将商放在al中,余数存于ah。2126 xorb dl, dl ! About to shift bits 8-9 of cylinder into dl 2127 shr dx, #1 2128 shr dx, #1 ! dl6.7 = high cylinder 2129 orb dl, ah ! dl0.5 = sector (0-origin) 2130 movb cl, dl ! cl0.5 = sector, cl6.7 = high cyl 2131 incb cl ! cl0.5 = sector (1-origin) 2132 movb dh, al ! dh = al = head 2133 movb dl, device(bp) ! dl = device to read 2134 movb al, (di) ! Sectors per track - Sector number (0-origin) 2135 subb al, ah ! = Sectors left on this track2136 cmpb al, (si) ! Compare with # sectors to read2137 jbe read ! Cant read past the end of a cylinder?2138 movb al, (si) ! (si) 0 2182 2183 mov si, #LOADOFF+rderr ! String to print Note that the strings on lines 2195-2196 occupy consecutive memory addresses and end at errend. One character at a time is printed until errend is reached. 2184 print: lodsb ! al = *si+ is char to be printed 2185 movb ah, #0x0E ! Print character in teletype mode 2186 mov bx, #0x0001 ! Page 0, foreground color 2187 int 0x10 ! Call BIOS VIDEO_IO int 0x10, ah=0x10 prints the character in al to the current cursor position and advances the cursor. bh holds the active page and bl holds the foreground color. 2188 cmp si, #LOADOFF+errend ! End of string reached? 2189 jb print Note that after reaching errend, the code falls through to hang. 2190 2191 ! Hang forever waiting for CTRL-ALT-DEL 2192 hang: jmp hang 2193 2194.data 2195 rderr: .ascii Read error 2196 errno: .ascii 00 2197 errend: 2198 2199 ! Floppy disk sectors per track for the 1.44M, 1.2M and 360K/720K types: 2200

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论