MBR结构解析与fdisk的bash实现

一、MBR结构解析

首先我们先介绍一些MBR的基本知识基础,再晾图片分析。MBR主要分为三大块分别是:

1、加载引导程序(446K)

2、分区表(64k)

3、标志结束位(2k)

加载引导程序:内容是因机器而异它里面正如其名,就是存放加载引导程序。现在主要的加载引导程序是LILO(LInux LOader)和 GNU GRUB(GRand Unified Boot loader)。

分区表:里面主要记录4个16K主分区的信息,我们将在下文进行详细介绍。

表示结束位:就是标志MBR结束,一般是0xaa55。如果不是,则告诉机器前面的内容是不合法的。

然后我们执行下面的命令一起来看看MBR内容:

# dd if=/dev/sdb bs=512 count=1 | hexdump -C


要看懂上图,我们得复习一下组成原理的基本知识。(1字节=1B=8二进制位=2个十六进制位)

然后上图中,左侧第一列是偏移量。由于每一行的数据是16k,所以每行偏移量0x10。根据我们上面的介绍,加载引导程序是446k、分区表是64k、标志结束位是2k。所以正如上图黑色区域和白色区域标志一样,我们得到了对应每个区域的范围如下:

加载引导程序:(00000000 第1字节~000001b0 第14字节)

分区表:(000001b0 第15字节~000001f0第14字节)

标志结束位:(000001f0第15字节~000001f0第16字节)

注:此处没有第0字节


由于分区表包涵了我们需要的大部分信息,接下来我们重点解析一下分区表。

000001b0  00 00 00 00 00 00 00 00  c8 87 da 95 00 0080 01

000001c0  01 00 07  fe   ff   ff   3f  00  00 00 06 73 41 06 00 fe

000001d0   ff   ff   0f   fe   ff   ff   45 73  41 06 bb 5c 01 1f00 00

000001e0  00 00 00 00 00 00 00  00 00 00 00 00 00 0000 00

000001f0   00 00 00 00 00 00 00 00  00 00 00 00 00 0055 aa

上图中,我们为4个分区的内容分别标上了不同颜色。我们为了方便解析每个字段,以第一个分区为例子。并且为每个字节分配一个名字。具体如下:

8001010007feffff3f00000006734106
status
f1f2f3parttype
l1l2l3lba1lba2lba3lba4s1s2s3s4

虽然看起来很多,但其实只有几类:

status:是否是可启动盘是的话就是0x80,否则就是0x00

f3+f2+f1:分区的开始位置

l3+l2+l1:分区的结束位置

s4+s3+s2+s1:分区的大小

parttype:分区类型,在fdisk中可以查看得到对应列表如下图。我这里第一个分区是07类型,也就是HPFS/NTFS的windows文件系统。第二个分区才是Linux。


二、fdisk验证

我们以第一个主分区为例子对某些字段进行简单的验证,下图是fdisk /dev/sdb的结果

Boot:第一个字节0x80说明第一个分区是可启动分区

Id:也就是parttype字段对应的值是0x07

System:根据id从fdisk的表格中得到HPFS/NTFS文件系统

Blocks:这里是s4s3s2s1=0x06417306,我们同样利用 echo "ibase=16;06417306/2" | bc 得到52476291k也刚好验证了上面的数值。

Start:这里f3f2f1=0x000101,我们利用echo “ibase=16;000101/2” | bc 得到128k。这里为什么是128k而不是上文fdisk中的1呢?主要是由于两个问题造成,第一个是fdisk的end和start中的数值是指磁盘的柱面。所以并不是简单的kB或者MB,因为根据磁盘型号不同,它每个柱面的大小容量也是不一样的。此外第二个原因是这里可能是由于磁盘的stripe造成的。(RAID卡配置--stripe size在每个磁盘上连续写入数据的总量,也称作“条带深度”。)stripe一般默认是128k。可能由于预设的原因所以不是从柱面0开始,而是从1开始。

(注:硬盘容量 =柱面数(表示每面盘面上有几条磁道,一般总数是1024) ×磁头数(表示盘面数) ×扇区数(表示每条磁道有几个扇区,一般总数是64)× 扇区(存储基本单元,大小一般为512B/4KB))

三、fdisk的bash实现

       前些实习的日子,找到了一个比较优美的bash代码。是检测MBR的启动分区、分区类型、大小等信息。这些信息也就是从我们上面介绍的分区表中得到。这里把代码拿出来,虽然实用性上不强(毕竟已经有fdisk)。但是拿出来一起学习,如果有不好的地方请指正哈。

#!/bin/bash
if [ -b $1 ];then
	mbr=`mktemp`
	echo "Reading MBR from device $1"
	dd if=$1 of=$mbr bs=512 count=1
	mbr_is_temporary=1
else
	mbr=$1
	if [ -r "$mbr" ];then
		echo "Reading MBR from file $mbr"
	else
		echo "Readable MBR required."
		exit 1
	fi
fi

od -v -t x1 -An -j 510 $mbr | grep -q " 55 aa$"
if [ "$?" -ne "0" ];then
	echo "MBR signature not found.Not a valid mbr."
	exit 1
fi

partmun=1
od -v -t x1 -An -j446 -N 64 $mbr | while read status f1 f2 f3 parttype l1 l2 l3 lba1 lba2 lba3 lba4 s1 s2 s3 s4
do
	if [ "$parttpye" == "00" ];then
		echo "Partition $parttpye is not defined"
	else
		case $status in
			00) bootable="unbootable";;
			80) bootable="bootable";;
			*) bootable="invail";;
		esac
		printf "Partiton %d is type %02s and is %s." $partnum $parttype $bootable
		sectors=`printf "%02s%02s%02s%02s\n" $s4 $s3 $s2 $s1 | tr '[:lower:]' '[:upper:]'`
		bytes=`echo "ibase=16; $sectors / 2" | bc`
		gb=`echo "scale=2; $bytes / 1000 / 1000" | bc`
		printf " Size %.02f GB \n" $gb
	fi
	partnum=`expr $partnum + 1`
done
if [ "$smb_is_temporary" ];then
	rm -f $mbr
fi


实现效果:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值