分享
 
 
 

Linux系统的引导过程和磁盘分区信息

王朝system·作者佚名  2008-05-19
窄屏简体版  字體: |||超大  

系统的引导过程和磁盘分区信息

在PC机上,最初的启动由BIOS完成。当开机自检(Power-On Self Test,POST)结束时, BIOS尝试读入磁盘的第一个扇区,把它看作引导扇区。由于大多数BIOS不提供SCSI支持,若要从SCSI磁盘启动,SCSI适配器要提供他自己的 BIOS。如果什么都找不到,老的BIOS会启动内置的ROM BASIC,或直接打印“NO ROM-BASIC”。

操作系统的启动分几步完成。由于引导扇区比较小,通常它主要任务是读入第二个loader,第二个loader再读入第三个loader,直到整个操作系统被完全读入。

硬盘的引导区:

代码:

OFFSET

0x000 JMP xx Near jump into the program code

0x003 Disk parameters

0x03E Program code loading the DOS kernel

0x1FE 0xAA55 Magic number for BIOS

可见,引导区的结构相对比较简单。它的长度总是512字节。重要的是引导区从0开始,以BIOS的0x1FE处的0xAA55结束。

从软盘启动比较简单,因为只有一个引导扇区:第一个扇区。硬盘则困难一些,它被分成很多分区。但是,BIOS根本不管分区信息,它象对待软盘一样对待硬盘,仍读入第一个分区,叫作:master boot record。(MBR)。所以MBR也应该和上面介绍的结构一样,在MBR的最后部分,有分区表。如下图:

代码:

OFFSET Length

0x000 0x1BE code loading and starting the boot sector of the active

partitian

0x1BE 0x010 partition1

0x1CE 0x010 partition2

0x1DE 0x010 partition3

0x1EE 0x010 partition4

0x1FE 0x0012 0xAA55 Disk parameters

从0x1BE处(即第462字节处)开始,是一个个主分区信息。每个分区信息占16字节,结构如下:

1 BOOT Boot flag: 0=not active ,0x80 active

1 HD Begin:head number

2 SEC CYL Begin:sector and cylinder number of boot sector

1 SYS System Code:0x83 linux , 0x82 linux swap etc。

1 HD End:head number

2 SEC CYL End: sector and cylinder number of boot sector

4 low byte high byte Relative sector number of start sector

4 low byte high byte Number of sectors in the partition

所以硬盘可以有4个主分区:primary prititions。假如它们不够用,可以设置所谓的扩展分区。扩展分区包含至少一个逻辑分区。扩展分区的第一个扇区结构类似MBR,它的分区表的第一表项对应第一个逻辑分区。如果存在第二个逻辑分区,那么分区表的第二个表项就包含了一个指针。这个指针指向第一个逻辑分区后面的一个地址,这个地址包含一个分区表,该分区表的第一表项对应第二个逻辑分区。这样就组成一个链表,从而扩展分区可以有任意多的逻辑分区。

每一个主分区和扩展区都包含一个引导扇区。系统只能从这几个地方之一启动。BOOT标志决定哪个区被引导。

MBR的代码要作以下的操作:

1:确定活动分区。

2:使用BIOS,将活跃分区的启动扇区读入。

3:跳到启动扇区的0位置。

MBR的空间足够完成这些工作。如上所述,每个分区理论上包含一个引导扇区,而且,存在的第二个硬盘也包含和第一个类似的结构。MBR完全可以容纳一个复杂的引导程序。即所谓的boot manager,动态的决定活动分区。Linux为我们提供了lilo及grub等工具来管理启动各启动项。

下面这段C程序可以用来检测磁盘分区信息以验证上述理论的正确性。

代码:

/* marco corvi <marco_corvi@geocities.com>

* @date

feb 2003

*

* \brief Read disk partition table

* modified by zhoulifa <zhoulifa@163.com http://zhoulifa.bokee.com

* 周立发 Linux爱好者 Linux知识传播者 SOHO族 开发者

*/

#include <stdio.h>

// printf

#include <stdlib.h>

// exit

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <errno.h>

#include <unistd.h>

int

main(int argc, char ** argv )

{

int fd;

unsigned char mbs[512]; // master boot sector

unsigned char * pp;

// partition pointer

int head, sect, cyl;

unsigned int sector;

int n;

if (argc <= 1) {

fprintf(stderr, "Usage: %s <device>\n", argv[0] );

exit(1);

}

fd = open( argv[1], O_RDONLY );

if ( fd < 0 ) {

fprintf(stderr, "Error: unable to open device %s\n", argv[1] );

perror("");

exit(1);

}

n = read( fd, mbs, 512);

close(fd);

if ( n < 512 ) {

fprintf(stderr, "Error: short read %d\n", n );

exit(1);

}

pp = mbs + 0x1BE;

for (n=0; n<4; n++) {

printf("PARTITION %d\n", n );

printf("Boot flag

%2x\n", pp[0] );

printf("System flag %2x\n", pp[4] );

// C/H/S as 10+8+6

if(argc == 3)

{

head = pp[1];

sect = pp[2]; sect = (sect<<2) | (pp[3]>>6);

cyl

= pp[3] & 0x3f;

/*

cyl = pp[1] >> 2;

head = ((pp[1] & 0x03)<<6) | (pp[2]>>2);

sect = pp[2] & 0x03;

sect = (sect << 8) | pp[3];

head = pp[1];

sect = pp[3]>>6;

sect = (sect<<8) | pp[2];

cyl

= pp[3] & 0x3f;

*/

printf("Start Cylinder %d Head %d Sector %d \n", cyl, head, sect );

head = pp[5];

sect = pp[6]; sect = (sect<<2) | (pp[7]>>6);

cyl

= pp[7] & 0x3f;

cyl = pp[5];

printf("End

Cylinder %d Head %d Sector %d \n", cyl, head, sect );

}

sector = pp[8] + (1<<8)*pp[9] + (1<<16)*pp[10] + (1<<24)*pp[11];

printf("Sector number %u\n", sector);

sector = pp[12] + (1<<8)*pp[13] + (1<<16)*pp[14] + (1<<24)*pp[15];

printf("Number of sectors %u\n", sector);

pp += 0x10;

}

}

编译此程序后可以直接运行,如果没有任何参数,会从/dev/partitions文件里读取相应信息。如果有参数,则第一个参数指明要查看的设备。

参考了 http://www.linuxdby.com/articlesdisplay.php?newsid=75 及 marco_corvi的“Linux kernel programming by example”,并在Red Hat Linux 7.2系统上验证通过。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有