Chinaunix首页 | 论坛 | 博客
  • 博客访问: 20853
  • 博文数量: 5
  • 博客积分: 186
  • 博客等级: 入伍新兵
  • 技术积分: 40
  • 用 户 组: 普通用户
  • 注册时间: 2009-10-30 22:28
文章分类
文章存档

2011年(5)

分类:

2011-11-26 06:06:13

  1 !   masterboot 2.0 - Master boot block code     Author: Kees J. Bot
  2 !
  3 ! This code may be placed in the first sector (the boot sector) of a floppy,
  4 ! hard disk or hard disk primary partition.  There it will perform the
  5 ! following actions at boot time:
  6 !
  7 ! - If the booted device is a hard disk and one of the partitions is active
  8 !   then the active partition is booted.
  9 !
 10 ! - Otherwise the next floppy or hard disk device is booted, trying them one
 11 !   by one.
 12 !
 13 ! To make things a little clearer, the boot path might be:
 14 !   /dev/fd0    - Floppy disk containing data, tries fd1 then d0
 15 !   [/dev/fd1]  - Drive empty
 16 !   /dev/c0d0   - Master boot block, selects active partition 2
 17 !   /dev/c0d0p2 - Submaster, selects active subpartition 0
 18 !   /dev/c0d0p2s0   - Minix bootblock, reads Boot Monitor /boot
 19 !   Minix       - Started by /boot from a kernel image in /minix
 20
 21 ! boot sequence:
 22 ! 1. If a hard drive partition:
 23 ! masterboot(this code) -> bootstrap -> bootmonitor -> boot_MinixOperatingSystem
 24 ! 2. If a hard drive subpartition is booted:
 25 ! masterboot(this code) -> masterboot(again) -> bootstrap -> bootmonitor -> boot_MinixOperatingSystem
 26
 27
 28     LOADOFF       =    0x7C00    ! 本程序自动被Bios加载到这里.
 29     BUFFER    =    0x0600 ! First free memory
 30     PART_TABLE =      446    ! 分区表的入口位置,也即是代码段的大小. 1BE
 31     PENTRYSIZE =       16    ! 分区表每项16字节.(共4项, 共64字节)
 32     MAGIC     =       510  ! Location of the AA55 magic number ! (1FE, 1FF)  (510, 511)
 33
 34     ! .h:
 35     bootind       =         0
 36     sysind    =         4
 37     lowsec    =         8
 38
 39 .text
 40
 41 ! Find active (sub)partition, load its first sector, run it.
 42 master:
 43     xor    ax, ax
 44     mov    ds, ax
 45     mov    es, ax
 46     cli                    ! 给ss,sp传值前要关闭中断响应
 47     mov    ss, ax         ! ds = es = ss = Vector segment
 48     mov    sp, #LOADOFF
 49     sti                    ! 重新打开中断响应
 50
 51     ! 复制本程序到BUFFER处去执行
 52     mov    si, sp         ! si = start of this code
 53     push   si            ! Also where we'll return to eventually
 54     mov    di, #BUFFER        ! Buffer area
 55     mov    cx, #512/2     ! One sector
 56     cld            ! 方向位清零, 使得复制到的是0:LOADOFF+512而不是0:LOADOFF-512
 57                 ! rep: repeats execution of string instructions while cx != 0.
 58     rep movs    ! 从DS:SI复制数据到ES:DI.(一次复制1 word而不是1 bite??) ! ?????
 59     jmpf   BUFFER+migrate, 0 ! far jmp. 0:BUFFER+migrate
 60 !
 61 !上面的代码块把mbr的512字节移动到0x0000:0x0600处,然后跳转到migrate的代码处执行.
 62 !接下来首先测试设备是否可引导,即dl的最高位是否为1, 为1则设备可引导; 否
 63 !则跳转到nextdisk处.
 64 !如果可引导则检测的分区,测试其类型同时是否是活动分区,总共测试4次,如果
 65 !还没有找到则显示没有活动分区,然后直接跳到reboot的地方执行,显示一些信息后系统重启.
 66 !
 67 migrate:
 68 ! Find the active partition
 69 findactive:
 70     ! ## testb sets the sign flag if the value in dl is negative. Remember that 0x00
 71     ! and 0x01 correspond to the first and second floppy drives and 0x80, 0x81,
 72     ! 0x82, and 0x83 correspond to hard drives 1-4.
 73     testb  dl, dl       ! dl是负的吗?若是,则符号标记位被置位. dl的值从何来?????
 74     jns    nextdisk       ! 如果为正数的话,是软盘,则跳转到nextdisk;
 75     mov    si, #BUFFER+PART_TABLE ! 否则为硬盘.
 76 find:   cmpb  sysind(si), #0   ! Partition type, nonzero when in use
 77     jz nextpart
 78     testb  bootind(si), #0x80   ! Active partition flag in bit 7
 79     jz nextpart        ! It's not active
 80 loadpart:
 81     call   load      ! Load partition bootstrap ! 为什么不是 call load0 ?????
 82     jc error1          ! Not supposed to fail
 83 bootstrap:
 84     ret                    ! Jump to the master bootstrap
 85 nextpart:
 86     add    si, #PENTRYSIZE
 87     cmp    si, #BUFFER+PART_TABLE+4*PENTRYSIZE ! 最多有4个主分区
 88     jb find
 89 ! No active partition, tell 'em
 90     !利用call命令会把下一条要执行的指令的地址压人堆栈的特点吧.ascii字符的初始地址给压人了堆栈
 91     !这样当进入print函数后就可以通过弹栈把字符的首地址取出,最后字符显示完后直接用jmp
 92     !(si)指令跳转到下一个地方继续执行
 93     call   print
 94     .ascii "No active partition\0"
 95     jmp    reboot
 96
 97 ! There are no active partitions on this drive, try the next drive.
 98 nextdisk:
 99     incb   dl            ! Increment dl for the next drive
100     testb  dl, dl
101     js nexthd          ! Hard disk if negative
102     ! ! INT 11 - BIOS - GET EQUIPMENT LIST
103     ! ! Return: (E)AX = BIOS equipment list word (see #00226,#03215 at INT 4B"Tandy")
104     int    0x11           ! Get equipment configuration
105     shl    ax, #1         ! Highest floppy drive # in bits 6-7
106     shl    ax, #1         ! Now in bits 0-1 of ah
107     andb   ah, #0x03     ! Extract bits
108     cmpb   dl, ah            ! Must be dl <= ah for drive to exist
109     ja nextdisk        ! Otherwise try disk 0 eventually
110     call   load0         ! Read the next floppy bootstrap
111     jc nextdisk        ! It failed, next disk please
112     ret                ! Jump to the next master bootstrap
113 nexthd: call    load0          ! Read the hard disk bootstrap
114 error1: jc  error            ! No disk?
115     ret
116
117
118 ! Load sector 0 from the current device.  It's either a floppy bootstrap or
119 ! a hard disk master bootstrap.
120 load0:
121     mov    si, #BUFFER+zero-lowsec    ! si = where lowsec(si) is zero ! 这是什么意思?????
122     !jmp   load
123
124 ! Load sector lowsec(si) from the current device.  The obvious head, sector,
125 ! and cylinder numbers are ignored in favour of the more trustworthy absolute
126 ! start of partition.
127 load:
128     mov    di, #3     ! Three retries for floppy spinup !  
129 retry:  push dx  ! Save drive code
130     push   es
131     push   di        ! Next call destroys es and di
132     movb   ah, #0x08 ! Code for drive parameters
133     ! ! INT 13 - DISK - GET DRIVE PARAMETERS (PC,XT286,CONV,PS,ESDI,SCSI)
134         ! ! AH = 08h
135         ! ! ES:DI = 0000h:0000h to guard against BIOS bugs
136     ! ! Return: CF set on error
137             ! ! CF clear if successful
138             ! ! CL = maximum sector number (bits 5-0),high two bits of maximum cylinder number (bits 7-6)
139             ! ! DH = maximum head number
140     ! 获取该设备的一些参数
141     int    0x13! 获取该设备的一些参数
142     pop    di
143     pop    es
144
145     ! 处理这些参数
146     andb   cl, #0x3F ! cl = max sector number (1-origin) ! cl&63. <63>
147     incb   dh            ! dh = 1 + max head number (0-origin). <255>
148     movb   al, cl        ! al = cl = sectors per track
149     mulb   dh            ! dh = heads, ax = heads * sectors. ! ax=al*dh.
150     ! 每柱面扇区数 = 每道扇区数 * 每柱面磁头数 = 63 * 255 = 16065
151     mov        bx, ax        ! bx = sectors per cylinder = heads * sectors. <16065>
152     mov        ax, lowsec+0(si)
153     mov        dx, lowsec+2(si)! dx:ax = sector within drive    ! 硬盘一个扇区=512KB
154     cmp        dx, #[1024*255*63-255]>>16  ! bootable在8GB之后? ! 只须比较lowsec高16位. 8GB约等于1024*255*63个扇区. 是这个意思吗?????
155     jae        bigdisk       ! 在8GB之后, 跳转
156
157     ! 在8GB之前, 把逻辑扇区号转换为 C/H/S 形式, 以便调用bios把它加载到内存.
158         ! L = C*16065 + H*63 + S - 1  ==>
159         ! C =  L / 16065
160         ! H = (L % 16065) / 63
161         ! S = (L % 16065) % 63 + 1
162     div        bx            ! ax = cylinder, dx = sector within cylinder.    ! dx:ax/bx=ax...dx
163     xchg   ax, dx        ! ax = sector within cylinder, dx = cylinder
164     movb   ch, dl        ! ch = low 8 bits of cylinder<柱面号-低8位>
165     divb   cl            ! al<磁头号> = head, ah = sector (0-origin)       ! ax/cl=al...ah
166     xorb   dl, dl        ! About to shift bits 8-9 of cylinder into dl
167     shr        dx, #1
168     shr        dx, #1        ! dl[6..7] = high cylinder
169     orb        dl, ah        ! dl[0..5] = sector (0-origin)
170     movb   cl, dl        ! cl[0..5] = sector<扇区号-低6位>, cl[6..7] = high cyl<柱面号-高2位>
171     incb   cl            ! cl[0..5] = sector (1-origin)
172     pop        dx            ! Restore drive code in dl<设置号>
173     movb   dh, al        ! dh = al = head<磁头号>
174     mov        bx, #LOADOFF! es:bx = where sector is loaded. 把该扇区加载到这里!!!!!
175     mov        ax, #0x0201   ! Code for read, just one sector  ah=2 al=1<一共读取1个扇区>
176     ! ! INT 13 - DISK - READ SECTOR(S) INTO MEMORY
177         ! ! AH = 02h
178         ! ! AL = number of sectors to read (must be nonzero)
179         ! ! CH = low eight bits of cylinder number
180         ! ! CL = sector number 1-63 (bits 0-5) high two bits of cylinder (bits 6-7, hard disk only)
181         ! ! DH = head number
182         ! ! DL = drive number (bit 7 set for hard disk)
183         ! ! ES:BX -> data buffer
184     ! ! Return: CF set on error
185         ! ! if AH = 11h (corrected ECC error), AL = burst length
186         ! ! CF clear if successful
187         ! ! AH = status (see #00234)
188         ! ! AL = number of sectors transferred (only valid if CF set for some BIOSes)
189     int    0x13       ! Call the BIOS for a read
190     jmp    rdeval     ! Evaluate read result
191
192 bigdisk:
193     mov        bx, dx        ! bx:ax = dx:ax = sector to read
194     pop        dx            ! Restore drive code in dl
195     push   si            ! Save si
196     mov        si, #BUFFER+ext_rw ! si = extended read/write parameter packet
197     mov        8(si), ax ! Starting block number = bx:ax
198     mov        10(si), bx
199     movb   ah, #0x42 ! Extended read
200     ! ! INT 13 - IBM/MS INT 13 Extensions - EXTENDED READ
201         ! ! AH = 42h
202         ! ! DL = drive number
203         ! ! DS:SI -> disk address packet (see #00272)
204     ! ! Return: CF clear if successful
205         ! ! CF set on error
206     int        0x13
207     pop        si        ! Restore si to point to partition entry
208     !jmp   rdeval
209 rdeval:
210     jnc        rdok      ! Read succeeded
211     cmpb   ah, #0x80 ! Disk timed out?  (Floppy drive empty)
212     je     rdbad
213     dec        di
214     jl     rdbad      ! Retry count expired
215     xorb   ah, ah
216     ! INT 13 - DISK - RESET DISK SYSTEM
217         ! AH = 00h
218         ! DL = drive (if bit 7 is set both hard disks and floppy disks reset)
219     ! Return: AH = status (see #00234)
220         ! CF clear if successful (returned AH=00h)
221         ! CF set on error
222     int    0x13       ! Reset ! CF set on error
223     jnc    retry      ! Try again
224 rdbad:
225     stc                ! Set carry flag
226     ret
227 rdok:   cmp   LOADOFF+MAGIC, #0xAA55
228     jne    nosig      ! Error if signature wrong
229     ret            ! Return with carry still clear ! 返回到LOADOFF执行刚成功加载的代码
230 nosig:  call print
231     .ascii "Not bootable\0"
232     jmp    reboot
233
234 ! A read error occurred, complain and hang
235 error:
236     mov    si, #LOADOFF+errno+1
237 prnum:  movb al, ah      ! Error number in ah
238     andb   al, #0x0F ! Low 4 bits
239     cmpb   al, #10       ! A-F?
240     jb digit       ! 0-9!
241     addb   al, #7        ! 'A' - ':'
242 digit:  addb (si), al    ! Modify '0' in string
243     dec    si
244     movb   cl, #4        ! Next 4 bits
245     shrb   ah, cl
246     jnz    prnum      ! Again if digit > 0
247     call   print
248     .ascii "Read error "
249 errno:  .ascii   "00\0"
250     !jmp   reboot
251
252 reboot:
253     call   print
254     .ascii ".  Hit any key to reboot.\0"
255     xorb   ah, ah        ! Wait for keypress ! ah=0
256     int    0x16 ! 读键盘字符
257     call   print
258     .ascii "\r\n\0"
259     int    0x19 ! 重新引导装入程序, 即重起
260
261 ! Print a message.
262 print:  pop  si       ! si = address of String following 'call print'
263 prnext: lodsb           ! al = *si++ is char to be printed
264     testb  al, al       ! Null marks end
265     jz prdone
266     movb   ah, #0x0E ! Print character in teletype mode
267     mov    bx, #0x0001    ! Page 0, foreground color
268     int    0x10 ! ah=0E, int 0x10 显示字符并自动处理光标; al=要显示的字符, bh=页号
269     jmp    prnext
270 prdone: jmp (si)        ! Continue after the string
271
272 .data
273
274 ! Extended read/write commands require a parameter packet.
275 ext_rw:
276     .data1 0x10        ! Length of extended r/w packet
277     .data1 0     ! Reserved
278     .data2 1       ! Blocks to transfer (just one)
279     .data2 LOADOFF     ! Buffer address offset
280     .data2 0     ! Buffer address segment
281     .data4 0     ! Starting block number low 32 bits (tbfi)
282 zero:   .data4    0   ! Starting block number high 32 bits
283 ! # zero:   .data4  0       ! Starting block number high 32 bits
284
285
286 ! 1. 硬盘第一扇区结构:
287     ! 0000   |------------------------------------------------|
288            ! |                                                |
289            ! |                                                |
290            ! |                Master Boot Record            |
291            ! |                                                |
292            ! |                                                |
293            ! |                主引导记录(446字节)            |
294            ! |                                                |
295            ! |                                                |
296            ! |                                                |
297     ! 01BD   |                                                |
298     ! 01BE 446------------------------------------------------|
299            ! |                                                |
300     ! 01CD   |              分区信息   1(16字节)              |
301     ! 01CE   |------------------------------------------------|
302            ! |                                                |
303     ! 01DD   |              分区信息   2(16字节)              |
304     ! 01DE   |------------------------------------------------|
305            ! |                                                |
306     ! 01ED   |              分区信息   3(16字节)              |
307     ! 01EE   |------------------------------------------------|
308            ! |                                                |
309     ! 01FD   |              分区信息   4(16字节)              |
310            ! |------------------------------------------------|      
311            ! | 01FE                    | 01FF                 |
312            ! |          55             |            AA        |
313            ! |------------------------------------------------|
314
315
316
317 ! 2. 分区表:
318      ! ========================================================================
319      ! |    字节                                   含义                       |
320    ! 0 ========================================================================
321      ! |  0            Activeflag.活动标志.若为0x80H,则表示该分区为活动分区.若|
322      ! |              为0x00H,则表示该分区为非活动分区.                       |
323      ! ------------------------------------------------------------------------
324      ! |               该分区的起始可用的空间的磁头号,扇区号,柱面号. 磁头号:第|
325      ! |1,2,3          1字节, 扇区号:第2字节低6位, 柱面号:第2字节高2位 + 第3字|
326      ! |               节.                                                    |
327    ! 4 ------------------------------------------------------------------------
328      ! |               分区文件系统标志:                                      |
329      ! |                           分区未用: 0x00H.                           |
330      ! |                           扩展分区: 0x05H, 0x0FH.                    |
331      ! |  4                        FAT16分区: 0x06H.                          |
332      ! |                           FAT32分区: 0x0BH, 0x1BH, 0x0CH, 0x1CH.     |
333      ! |                           NTFS分区: 0x07H.                           |
334    ! 5 ------------------------------------------------------------------------
335      ! |5,6,7          该分区的结束磁头号,扇区号,柱面号, 含义同上.            |
336    ! 8 ------------------------------------------------------------------------
337      ! |8,9,10,11      逻辑起始扇区号. 即该分区起点之前已用了的扇区数.        |
338   ! 12 ------------------------------------------------------------------------
339      ! |12,13,14,15    该分区所占用的扇区数.                                  |
340      ! ========================================================================
341
问题讨论见:
阅读(1768) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~