Process 1 Formats the Ramdisk and Replaces the Root Device

Một phần của tài liệu The art of linux kernel design (Trang 161 - 164)

In Section 2.3, the Ramdisk space has been set up and initialized. The Ramdisk is still a “blank disk” before a similar deal like “formatting,” but it cannot be used as a block device. Information for formatting is in the floppy disk of boot OS. Chapter 1 explains that the first sector is Bootsect, the four sectors behind are setup, and the next 240 sectors are the system module that contains the head, which is a total of 245 sectors. Formatting the Ramdisk information starts from the 256 sectors.

In the following, process 1 calls rd_load() to use the information of the sector in the floppy disk after 256 to format the Ramdisk and make it as a block device.

The execution code is as follows:

After entering rd_load(), call breada() to read-ahead data block from the floppy disk, which are boot block and super block, which are needed for formatting the Ramdisk.

Note: Now the root device is the floppy disk.

Breada() and bread() are similar; the difference is that the breada() function can read in a number of consecutive data blocks, a total of three (257, 256, and 258), including guide block 256 (although the guide blocks are not actually used) and super block 257. The principle of reading the data block from a floppy disk is the same as bread reading the hard disk data block (see the explanation in Section 3.3.1). After reading, you can see in Figure 3.35 that three consecutive data blocks are read into the buffer cache block; the super block is marked with a red box.

Then, analyze the super block information, including judging whether the file system is Minix or not, and whether the data blocks of the root file system will be loaded will more than the entire Ramdisk space. These conditions should be satisfied in order to continue to load the root file system. Release the buffer block after analyzing. These are shown as the first, second, and third steps in Figure 3.36.

//code path:kernel/blk_dev/hd.c:

int sys_setup(void * BIOS) {

……

if (NR_HD)

printk(“Partition table%s ok.\n\r”,(NR_HD>1)?“s”:“”);

rd_load();

mount_root();

return (0);

}

Kernel

Enable interrupt

0x00000 0x9FFFF 0xFFFFF 0x3FFFFF 0x5FFFFF 0xFFFFFF

Kernel code area Kernel data area

Breada rd_load Read some blocks and write

to the specific buffer block block

block+2 block+1

Process status

Process 0 Process 1

Ready Interruptible

Current process

ROM BIOS and VGA

Figure 3.35 Read root file system super block.

ROM BIOS and VGA

Kernel

Process status

Process 0 Process 1

Ready Interruptible

Current process

Enable interrupt

0x00000 0x9FFFF 0xFFFFF 0x3FFFFF 0x5FFFFF 0xFFFFFF

task_struct of process 1

The page that task_struct of process 1 resides

Step 1: backup super block

Step 3:

test data in the super block

Step 2:

release the buffer block that contains the super block

Figure 3.36 Backup super block and test data.

The code is as follows:

The system then calls breada, copies the file system content from the floppy disk to the Ramdisk and releases the buffer blocks to complete “format,” as shown in the first and second steps in Figure 3.37.

After copying, set the Ramdisk as the root device.

//code path:kernel/blk_dev/ramdisk.c:

void rd_load(void) {

struct buffer_head *bh;

struct super_block s;

int block = 256; /* Start at block 256 */

int I = 1;

int nblocks;

char *cp; /* Move pointer */

if (!rd_length) return;

printk(“Ram disk:%d bytes, starting at 0x%x\n”, rd_length, (int) rd_start);

if (MAJOR(ROOT_DEV) ! = 2) //if the root device is not floppy disk return;

bh = breada(ROOT_DEV,block+1,block,block+2,-1);

if (!bh) {

printk(“Disk error while looking for ramdisk!\n”);

return;

}

*((struct d_super_block *) &s) = *((struct d_super_block *) bh->b_data);

brelse(bh);

if (s.s_magic ! = SUPER_MAGIC) //if unsatisfied, it’s not Minix file system /* No ram disk image present, assume normal floppy boot */

return;

nblocks = s.s_nzones << s.s_log_zone_size; //calculate the block //numbers in Ramdisk if (nblocks > (rd_length >> BLOCK_SIZE_BITS)) {

printk(“Ram disk image too big! (%d blocks,%d avail)\n”, nblocks, rd_length >> BLOCK_SIZE_BITS);

return;

}

printk(“Loading%d bytes into ram disk... 0000k”, nblocks << BLOCK_SIZE_BITS);

……

}

//The code path:kernel/blk_dev/ramdisk.c:

void rd_load(void) {

……

printk(“Loading%d bytes into ram disk... 0000k”, nblocks << BLOCK_SIZE_BITS);

cp = rd_start;

while (nblocks) { //copy the file system from the floppy disk to the // Ramdisk

if (nblocks > 2)

bh = breada(ROOT_DEV, block, block+1, block+2, -1);

We will introduce the loading of the root file system.

Một phần của tài liệu The art of linux kernel design (Trang 161 - 164)

Tải bản đầy đủ (PDF)

(524 trang)