#以下内容为在虚拟机上的实验输出结果(黑色字体部分),红色文字为注释
#使用fdisk命令打印磁盘/dev/sdd的分区表
[root@linux partitiontable]# fdisk /dev/sdd
Command (m for help): p
Disk /dev/sdd: 4139 MB, 4139778048 bytes
#磁盘sdd有128个磁头,每个磁道有62个扇区,共1018个柱面
#更容易理解的表述:磁盘sdd有1018个柱面,每个柱面有128个磁道(对应于128个磁头),
#每个磁道有62个扇区,每个扇区有512个字节。分配分区的单位定义为一个柱面的容量,
#即128*62*512=4063232字节。块的大小为1024字节。
128 heads, 62 sectors/track, 1018 cylinders
Units = cylinders of 7936 * 512 = 4063232bytes
#Start和End的单位是柱面,柱面从1开始计数。注意在MBR的分区表内,柱面和磁头都是从0开始计数,但扇区是从1开始计数。主引导记录(Master Boot Record,缩写:MBR)位于(0柱面0磁头1扇区),大小为1个扇区(512bytes)。但是0柱面0磁头整个磁道,除了第一个扇区写入mbr外,不再分配给磁盘分区。这样磁盘sdd的第一个分区sdd1实际是从(0柱面1磁头1扇区)开始的。因此尽管给第一个分区分配了16个柱面(相当于63488个块),但实际只有63457个块,恰好少一个磁道的块数(31个块)。
Device Boot Start End Blocks Id System
/dev/sdd1 1 16 63457 83 Linux
/dev/sdd2 17 63 186496 83 Linux
/dev/sdd3 64 1018 3789440 83 Linux
Command (m for help): q
#Test程序是我写的一个直接从MBR扇区读取分区表的程序,代码将在文尾附上。
[root@linux partitiontable]# ./test sdd.mbr
non-bootable
from CHSAddr: head:1 sector:1 cylinder:0
partition type:131
to CHSAddr: head:127 sector:62 cylinder:15
OFFSET:62(sector) LENGTH:126914(sectors)
non-bootable
from CHSAddr: head:0 sector:1 cylinder:16
partition type:131
to CHSAddr: head:127 sector:62 cylinder:62
OFFSET:126976(sector) LENGTH:372992(sectors)
non-bootable
from CHSAddr: head:0 sector:1 cylinder:63
partition type:131
to CHSAddr: head:127 sector:62 cylinder:249
OFFSET:499968(sector) LENGTH:7578880(sectors)
#使用od命令输出分区表
[root@linuxpartitiontable]# od -tu1 -j446 sdd.mbr
0000676 0 1 1 0 131 127 62 15 62 0 0 0 194 239 1 0
0000716 0 0 1 16131 127 62 62 0240 1 0 0 177 5 0
0000736 0 0 1 63 131 127 254 249 0 161 7 0 0 165 115 0
0000756 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0000776 85 170
#include<stdio.h> #include <unistd.h> #include<sys/types.h> #include<sys/stat.h> #include<fcntl.h> #define PT_OFFSET 446 #define PT_LEN 16 #define PT_N 4 //Cylinder-Head-Sectoradderess type typedefstruct { unsigned char head:8; unsigned char sector:6; unsigned short cylinder:10; } CHS; voidprintPT(char *buf); intmain(int argc, char *argv[]) { int fd = open(argv[1], O_RDONLY); if(fd < 0) { perror("open"); exit(1); } if(lseek(fd, PT_OFFSET, SEEK_SET) ==-1) { close(fd); perror("lseek"); exit(1); } char buf[PT_LEN]; int i; for(i = 0; i < PT_N; i++) { bzero(buf, PT_LEN); if(read(fd, buf, PT_LEN) !=PT_LEN) { printf("can't getfull partition table[%d]\n", i); close(fd); exit(1); } if(buf[1] || buf[2] || buf[3]) printPT(buf); } close(fd); return 0; } voidprintPT(char *buf) { switch((unsigned char)buf[0]) { case 0x80: printf("bootable\n"); break; case 0x00: printf("non-bootable\n"); break; default: printf("invalid\n"); } CHS chs; memcpy(&chs, buf+1, 3); printf("from CHSAddr:\thead:%d\tsector:%d\t cylinder:%d\n", chs.head, chs.sector, chs.cylinder); printf("partition type:%d\n",(unsigned char)buf[4]); memcpy(&chs, buf+5, 3); printf("to CHSAddr:\thead:%d\tsector:%d\t cylinder:%d\n", chs.head, chs.sector, chs.cylinder); printf("OFFSET:%d(sector)\t",*(unsigned int*)&buf[8]); printf("LENGTH:%d(sectors)\n\n", *(unsignedint*)&buf[12]); }
地址 |
描述 |
长度 |
|||
Hex |
Oct |
Dec |
|||
|
|
0 |
代码区 |
440 (最大446) |
|
|
|
440 |
disk signature (optional) |
4 |
|
|
|
444 |
一般为空值; 0x0000 |
2 |
|
|
|
446 |
Table of primary partitions (四个16 byte的主分区表入口) |
64 |
|
|
|
510 |
55h |
MBR 有效标志: 0x55AA |
2 |
|
|
511 |
AAh |
||
MBR, 总大小: 446 + 64 + 2 = |
512 |
偏移 |
长度(字节) |
描述 |
00H |
1 |
分区状态:0x00-->非活动(不可引导)分区; 0x80--> 活动(可引导)分区; 其它数值没有意义 |
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 |
分区总的扇区数 |