Linux 中所有的设备都在/dev/目录下,硬盘命名规则是[x]d[y][n],其中只有字母 d 是固定的,其他带中括号的字符都是多选值,下面从左到右介绍各个字符。
-
x
表示硬盘分类,硬盘有两大类,IDE
磁盘和SCSI
磁盘。h
代表IDE
磁盘,s
代表SCSI
磁盘,故 x 取值为 h 和 s。 -
d
表示 disk,即磁盘。 -
y
表示设备号,以区分第几个设备,取值范围是小写字符,其中a
是第 1 个硬盘,b
是第 2 个硬盘, 依次类推。 -
n
表示分区号,也就是一个硬盘上的第几个分区。分区以数字 l 开始,依次类推。 综上所述, sda表示第 1 个SCSI
硬盘,hdc
表示第 3 个 IDE 硬盘, sdal 表示第 1 个 SCSI 硬盘的第 1 个分区, hdc3 表示第 3 个 IDE 硬盘的第 3 个分区。这里统一用 SCSI 硬盘的命名规则来命名虚拟硬盘 hd60M.img 和 hd80M。其中hd60M.img
为 sda,hd80M.img
为sdb。hd60M.img
是裸盘,没有文件系统和 分区,因此我们只处理hd80M.img
,将其上的主分区占据sdb[l~4]
,逻辑分区占据sdb[5~]
。
__attribute__
是gcc特有的关键字,用于告诉 gcc在编译时需要做些“特殊处理”, packed
就是“特殊处理”, 意为压缩的。__attribute__ ((packed))
即不允许编译器为对齐而在此结构中填充空隙,从而保证结构partition_table_entry的大小是 16 宇节,这与分区表项的大小是吻合的。
在vs中,可以使用类似的代码
#pragma pack(push)
#pragma pack(__packed__)
typedef struct{
int a;
char b;
long l;
}test1;
typedef struct{
char a1;
char a2;
test1 t1;
double b1;
} test2;
#pragma pack(pop)
扇区的结构
/*------------------ partition structure define ------------------------------- */
//partition_table struct (16byte)
struct partition_table_entry {
uint8_t bootable; // 是否可引导
uint8_t start_head; // 起始磁头号
uint8_t start_sec; // 起始扇区号
uint8_t start_cylinder; // 起始柱面号
uint8_t fs_type; // 分区类型
uint8_t end_head; // 结束磁头号
uint8_t end_sector; // 结束扇区号
uint8_t end_cylinder; // 结束柱面号
uint32_t start_lba; // 本分区起始扇区的lba地址
uint32_t sec_cnt; // 本分区的扇区数目
} __attribute__ ((packed)); // pack struct to ensure 16byte size
//boot_sector (store mbr/ebr)
struct boot_sector {
uint8_t other[446]; // boot code
struct partition_table_entry partition_table[4]; // four partition_tables, 64bytes
uint16_t signature; // boot sector ends with 0x55,0xaa
} __attribute__ ((packed));
/*----------------------------------------------------------------------------- */
此处在global.h
中定义
#define UNUSED __attribute__((unused))
表示某个变量或函数不会用到,避免编译器产生警告信息
网友评论