注意:这是一篇从旧博客恢复的文章。
硬盘基本知识
参考维基百科:硬盘
A:磁道
B:扇面
C:扇区
D:簇(扇区组)
硬盘有数个盘片,每盘片两个面,每个面一个磁头。
当磁盘旋转时,磁头若保持在一个位置上,则每个磁头都会在磁盘表面划出一个圆形轨迹,这些圆形轨迹就叫做磁道。
处于同一半径圆的多个磁道组成一个柱面。
每面磁道数=柱面数
容量=面(磁头)数每面磁道数每磁道扇区数*每扇区字节数
每扇区字节数通常为512字节
计算机启动过程
参考:计算机是如何启动的?
引用回复中的一段话(有修改):
- 计算机开机时,CPU(x86架构)默认执行0ffffh:0000h处的指令,而此内存地址应该存放的就是bios rom
- bios执行完post等后,将引导设备的mbr复制到内存地址0:7c00h处,跳转执行此处指令
- 现在一般引导设备中的mbr是grub或lilo这样的引导程序,这样的程序首先将自己复制到0:6c00h处执行,在主分区表中搜索活动分区,将用户选择的活动分区的第一个扇区读入到07c00h处,调转到07c00h处执行。注:以上均在实模式中执行,还未进入保护模式
- 为加载内核做准备,并将控制权交给kernel,系统启动成功。注:这一步进入保护模式
当然这是现在一般的启动流程,当然如果自己写os,可以直接在引导设备的mbr中写直接加载内核的代码,将编译的代码dd入引导设备的mbr中即可。
我们需要知道的是,执行完BIOS之后,就会把硬盘的0面0磁道1扇区(扇区从1开始计数)的512字节复制到0:7c00h,并修改CS:IP到此处。
MBR的结构
参考维基百科:主引导记录(Master Boot Record,缩写:MBR)
地址 | 描述 | 长度 (字节) | |||
---|---|---|---|---|---|
Hex | Oct | Dec | |||
0000 |
0000 |
0 | 代码区 | 440 (最大 446) | |
01B8 |
0670 |
440 | 选用磁盘标志 | 4 | |
01BC |
0674 |
444 | 一般为空值; 0x0000 | 2 | |
01BE |
0676 |
446 | 标准 MBR 分区表规划 (四个16 byte的主分区表入口) | 64 | |
01FE |
0776 |
510 | 55h | MBR 有效标志: 0x55AA | 2 |
01FF |
0777 |
511 | AAh | ||
MBR, 总大小: 446 + 64 + 2 = | 512 |
也就是说,CPU复制到0:7c00h的512字节,包括了代码和分区表。
其中,代码区的内容就是一段16位汇编程序,内容是一个boot loader,即引导加载程序,在windows中就是一个选操作系统的菜单。而在linux中普遍使用grub,grub程序就存在于这个代码区。
从MBR的格式中可以看出,MBR格式的分区表结构,分区可以精确到扇区。不过鸟哥的书中说是只能精确到柱面。为此我在虚拟机中测试了一下,用DiskGenius分区,确认确实是可以精确到扇区的。
分区表结构
MBR分区表提供4个分区表项位置,每个分区用16个字节描述。这16个字节的组成如下:
偏移 | 长度(字节) | 意义 |
---|---|---|
00H | 1 | 分区状态:00-->非活动分区;80--> 活动分区; 其它数值没有意义 |
01H | 1 | 分区起始磁头号(HEAD),用到全部8位 |
02H | 2 | 分区起始扇区号(SECTOR),占据02H的位0-5; 该分区的起始磁柱号(CYLINDER),占据 02H的位6-7和03H的全部8位 |
04H | 1 | 文件系统标志位 |
05H | 1 | 分区结束磁头号(HEAD),用到全部8位 |
06H | 2 | 分区结束扇区号(SECTOR),占据06H的位0-5; 该分区的结束磁柱号(CYLINDER),占据 06H的位6-7和07H的全部8位 |
08H | 4 | 分区起始相对扇区号 |
0CH | 4 | 分区总的扇区数 |
其中文件系统标志位可以参考维基百科:文件系统标志位
MBR只有4个分区表项位置,也就是说,只能有4个分区。但是MBR使用扩展分区的方法实现了多分区。
引用维基百科的一段话:
从主引导记录的结构可以知道,它仅仅包含一个64个字节的硬盘分区表。由于每个分区信息需要16个字节,所以对于采用MBR型分区结构的硬盘,最多只能识别4个主要分区(Primary partition)。所以对于一个采用此种分区结构的硬盘来说,想要得到4个以上的主要分区是不可能的。这里就需要引出扩展分区了。扩展分区也是主要分区的一种,但它与主分区的不同在于理论上可以划分为无数个逻辑分区。
扩展分区中逻辑驱动器的引导记录是链式的。每一个逻辑分区都有一个和MBR结构类似的扩展引导记录(EBR),其分区表的第一项指向该逻辑分区本身的引导扇区,第二项指向下一个逻辑驱动器的EBR,分区表第三、第四项没有用到。
也就是说,一个扩展分区相当于一个链式结构,只需要有头指针就可以得到这一串分区的信息。
在MBR分区表中最多4个主分区或者3个主分区+1个扩展分区。 扩展分区只能有一个,它可以串起来多个逻辑分区。
意思就是扩展分区也要占用4个分区位置当中的一个,但是这个位置所表示的分区可以是一个串。
MBR引导代码
在虚拟机里创建一个硬盘,启动PE,使用Paragon Partition Manager读取出0面0磁道1扇区(当然也可以启动linux,用linux的工具),数据如下:
在这里是windows的boot loader
(上图中的MBR的分区情况是1个主分区,3个逻辑分区)
对代码反汇编如下(注释在代码中):
点击图标↔可以expand code
0:7C00 33C0 XOR AX,AX
0:7C02 8ED0 MOV SS,AX
0:7C04 BC007C MOV SP,7C00 ;ss:sp -> 0:7c00
0:7C07 FB STI ;屏蔽中断
0:7C08 50 PUSH AX
0:7C09 07 POP ES
0:7C0A 50 PUSH AX
0:7C0B 1F POP DS ;es=ds=0
0:7C0C FC CLD
0:7C0D BE1B7C MOV SI,7C1B
0:7C10 BF1B06 MOV DI,061B
0:7C13 50 PUSH AX
0:7C14 57 PUSH DI
0:7C15 B9E501 MOV CX,01E5
0:7C18 F3 REPZ
0:7C19 A4 MOVSB ;复制[0:7c1bh,0:7E00)的01e5字节到0:061b
0:7C1A CB RETF ;cs:ip -> 0:061b
;原0:7C1B 下面偏移地址记录为复制的代码的地址 相当于偏移了-7600
0:061B BDBE07 MOV BP,07BE
0:061E B104 MOV CL,04
0:0620 386E00 CMP [BP+00],CH ;由于之前repz movsb操作,cx为0结束循环,ch为0
0:0623 7C09 JL 062E ;80h是负数,因此是判断是否为活动分区,是则跳转
0:0625 7513 JNZ 063A ;判断是否为非活动分区,不是则跳转
0:0627 83C510 ADD BP,+10 ;BP指向下一个分区表项
0:062A E2F4 LOOP 0620 ;循环对4个分区表项操作
0:062C CD18 INT 18 ;如果4个分区表项全都是非活动分区,则会执行到此,执行ROM BASIC
0:062E 8BF5 MOV SI,BP ;是活动分区则跳转至此
0:0630 83C610 ADD SI,+10
0:0633 49 DEC CX
0:0634 7419 JZ 064F ;分区检测完后跳转
0:0636 382C CMP [SI],CH
0:0638 74F6 JZ 0630 ;判断是否为非活动分区,是则检测下一个分区表项
0:063A A0B507 MOV AL,[07B5] ;不是活动分区也不是非活动分区则跳转至此,显示错误信息
0:063D B407 MOV AH,07 ;这个分区表不完整,显示的信息可能也有些问题
0:063F 8BF0 MOV SI,AX
0:0641 AC LODSB ;从[si]读入一个字节到al
0:0642 3C00 CMP AL,00
0:0644 74FC JZ 0642 ;如果当前处理的字节是0,则向上跳转,相当于while(1)
0:0646 BB0700 MOV BX,0007
0:0649 B40E MOV AH,0E
0:064B CD10 INT 10 ;与上面对bx ah的设置一起,显示一个al字符
0:064D EBF2 JMP 0641
0:064F 884E10 MOV [BP+10],CL ;分区检测完后跳转至此
;接下来实现的功能是把活动分区对应的第一个扇区的512个字节数据读到0000:7C00处
;cs:ip指向0000:7c00,执行活动分区的系统引导程序
;实在无力逐句翻译了……
0:0652 E84600 CALL 069B
0:0655 732A JNB 0681
0:0657 FE4610 INC BYTE PTR [BP+10]
0:065A 807E040B CMP BYTE PTR [BP+04],0B
0:065E 740B JZ 066B
0:0660 807E040C CMP BYTE PTR [BP+04],0C
0:0664 7405 JZ 066B
0:0666 A0B607 MOV AL,[07B6]
0:0669 75D2 JNZ 063D
0:066B 80460206 ADD BYTE PTR [BP+02],06
0:066F 83460806 ADD WORD PTR [BP+08],+06
0:0673 83560A00 ADC WORD PTR [BP+0A],+00
0:0677 E82100 CALL 069B
0:067A 7305 JNB 0681
0:067C A0B607 MOV AL,[07B6]
0:067F EBBC JMP 063D
0:0681 813EFE7D55AA CMP WORD PTR [7DFE],AA55
0:0687 740B JZ 0694
0:0689 807E1000 CMP BYTE PTR [BP+10],00
0:068D 74C8 JZ 0657
0:068F A0B707 MOV AL,[07B7]
0:0692 EBA9 JMP 063D
0:0694 8BFC MOV DI,SP
0:0696 1E PUSH DS
0:0697 57 PUSH DI
0:0698 8BF5 MOV SI,BP
0:069A CB RETF
0:069B BF0500 MOV DI,0005
0:069E 8A5600 MOV DL,[BP+00]
0:06A1 B408 MOV AH,08
0:06A3 CD13 INT 13
0:06A5 7223 JB 01CA
0:06A7 8AC1 MOV AL,CL
0:06A9 243F AND AL,3F
0:06AB 98 CBW
0:06AC 8ADE MOV BL,DH
0:06AE 8AFC MOV BH,AH
0:06B0 43 INC BX
0:06B1 F7E3 MUL BX
0:06B3 8BD1 MOV DX,CX
0:06B5 86D6 XCHG DL,DH
0:06B7 B106 MOV CL,06
0:06B9 D2EE SHR DH,CL
0:06BB 42 INC DX
0:06BC F7E2 MUL DX
0:06BE 39560A CMP [BP+0A],DX
0:06C1 7723 JA 01E6
0:06C3 7205 JB 01CA
0:06C5 394608 CMP [BP+08],AX
0:06C8 731C JNB 01E6
0:06CA B80102 MOV AX,0201
0:06CD BB007C MOV BX,7C00
0:06D0 8B4E02 MOV CX,[BP+02]
0:06D3 8B5600 MOV DX,[BP+00]
0:06D6 CD13 INT 13
0:06D8 7351 JNB 022B
0:06DA 4F DEC DI
0:06DB 744E JZ 022B
0:06DD 32E4 XOR AH,AH
0:06DF 8A5600 MOV DL,[BP+00]
0:06E2 CD13 INT 13
0:06E4 EBE4 JMP 01CA
0:06E6 8A5600 MOV DL,[BP+00]
0:06E9 60 DB 60
0:06EA BBAA55 MOV BX,55AA
0:06ED B441 MOV AH,41
0:06EF CD13 INT 13
0:06F1 7236 JB 0229
0:06F3 81FB55AA CMP BX,AA55
0:06F7 7530 JNZ 0229
0:06F9 F6C101 TEST CL,01
0:06FC 742B JZ 0229
0:06FE 61 DB 61
0:06FF 60 DB 60
;原7D00
0:0700: 6A 00 6A 00 FF 76 0A FF 76 08 6A 00 68 00 7C 6A ;
0:0710: 01 6A 10 B4 42 8B F4 CD 13 61 61 73 0E 4F 74 0B ;
0:0720: 32 E4 8A 56 00 CD 13 EB D6 61 F9 C3 49 6E 76 61 ; a Inva
0:0730: 6C 69 64 20 70 61 72 74 69 74 69 6F 6E 20 74 61 ; lid partition ta
0:0740: 62 6C 65 00 45 72 72 6F 72 20 6C 6F 61 64 69 6E ; ble.Error loadin
0:0750: 67 20 6F 70 65 72 61 74 69 6E 67 20 73 79 73 74 ; g operating syst
0:0760: 65 6D 00 4D 69 73 73 69 6E 67 20 6F 70 65 72 61 ; em.Missing opera
0:0770: 74 69 6E 67 20 73 79 73 74 65 6D 00 00 00 00 00 ; ting system
0:0780: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0:0790: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0:07A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0:07B0: 00 00 00 00 00 00 00 00
;非代码区(分区表等,根据分区不同而不同)
;原7D88
0:07B0: (07B8->) E2 B6 E2 B6 00 00 80 01
0:07C0: 01 00 07 07 FF 3B 3F 00 00 00 E1 5D 06 00 00 00
0:07D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0:07E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0:07F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 AA ;至此512字节结束
0:0800: ;原7E00
Comments
注:如果长时间无法加载,请针对 disq.us | disquscdn.com | disqus.com 启用代理。