3.3.3 Process 1 Loads the Root File System into the Root Device
3.3.3.3 Associate the Root File System with Process 1
The system sets the members of task_struct that is related to the file system i node and binds the root i node with the current process (process 1), as shown in Figure 3.47.
The code is as follows:
//the code path:fs/super.c:
void mount_root(void) {
……
if (!(mi = iget(ROOT_DEV,ROOT_INO))) //the root I-node of root device panic(“Unable to read root i-node”);
mi->i_count + = 3 ; /* NOTE! it is logically used 4 times, not 1 */
p->s_isup = p->s_imount = mi; //The important step
current->pwd = mi; //the current process manage the root //I-node of root file system
current->root = mi; //The parent-child create mechanism will //inherit this attribute to child process
……
}
ROOT BIOS and VGA
Kernel
Enable interrupt
0x00000 0x9FFFF 0xFFFFF 0x3FFFFF 0x5FFFFF 0xFFFFFF
Kernel code area Kernel data area
iget mount_root
inode_table[32]
Find the position of i node of root directory in the inode_table[32] by calling iget Process status
Process 0 Process 1
Ready Interruptible
Current process Figure 3.45 Read the root i node.
After getting the super block of the root file system, we can identify the status (occu- pied or free) of the Ramdisk through the information recorded in the super block and record this information in the buffer that was mentioned in Section 3.3.3.1. The code is as follows:
//the code path:fs/super.c:
void mount_root(void) {
……
free = 0;
i = p->s_nzones;
while (— — i > = 0) //calculate the number of free logical blocks if (!set_bit(i&8191,p->s_zmap[i>>13]->b_data))
free++;
printk(“%d/%d free blocks\n\r”,free,p->s_nzones);
free = 0;
i = p->s_ninodes+1;
while (— — i > = 0) //calculate the number of free I-node in the
//Ramdisk
if (!set_bit(i&8191,p->s_imap[i>>13]->b_data)) free++;
printk(“%d/%d free inodes\n\r”,free,p->s_ninodes);
}
ROM BIOS and VGA
Kernel
Enable interrupt
0x00000 0x9FFFF 0xFFFFF 0x3FFFFF 0x5FFFFF 0xFFFFFF
Kernel code area Kernel data area
iget
read_inode
mount_root
inode_table[32]
Find the position of root directory i node in
the i node table of root directory by calling read_inode Process status
Process 0 Process 1
Ready Interruptible
Current process
Figure 3.46 Read the i node.
At this stage, the function sys_setup is completed. This function is called by a soft interrupt; hence, return to system_call, and after that, call the function ret_from_sys_call.
Now, the current process is process 1; thus, the following will call the function do_signal (as long as the current process is not process 0, it would execute the function do_signal) to detect the bitmap of the current process. The code is as follows:
//the code path:kernel/system_call.s:
……
ret_from_sys_call:
movl _current,%eax # task[0] cannot have signals cmpl _task,%eax
je 3f
cmpw $0x0f,CS(%esp) # was old code segment supervisor ?
jne 3f
cmpw $0x17,OLDSS(%esp) # was stack segment = 0x17 ? jne 3f
movl signal(%eax),%ebx #the following would get the
#signal bitmap movl blocked(%eax),%ecx
notl %ecx andl %ebx,%ecx bsfl %ecx,%ecx
ROM BIOS and VGA
Kernel
Enable interrupt
0x00000 0x9FFFF 0xFFFFF 0x3FFFFF 0x5FFFFF 0xFFFFFF
Kernel code area Kernel data area
mount_root
inode_table[32] super_block[8]
task_struct of process 1
The page that task_struct of process 1 resides
Load super block
Set information of root i node Process status
Process 0 Process 1
Ready Interruptible
Current process
Figure 3.47 Finish loading the root file system and return.
Now, the current process (process 1) does not receive any signal, so there is no need to call do_signal.
At this point, sys_setup has finished and process 1 will return to the calling point mentioned in Section 3.3, preparing the code below.
In this chapter, we introduce how the system creates process 1, installs the hard disk file system, “formats” the Ramdisk and makes it as the root device, and loads the root file system into the Ramdisk. After all done, we will explain how process 1 creates process 2 and finish the shell, which is the human–computer interface of the OS.
je 3f
btrl %ecx,%ebx
movl %ebx,signal(%eax) incl %ecx
pushl %ecx
call _do_signal #call the function do_signal( )
……
//the code path:init/main.c:
void init(void) {
……
int pid,i;
setup((void *) &drive_info);
(void) open(“/dev/tty0”,O_RDWR,0);
(void) dup(0);
(void) dup(0);
printf(“%d buffers =%d bytes buffer space\n\r”,NR_BUFFERS, NR_BUFFERS*BLOCK_SIZE);
……
}
This page intentionally left blank This page intentionally left blank
4.1 Open the Terminal Device File and Copy the File Handle
Shell is a user-interface (UI) process. Through shell, computer users implement human–
computer interactions with operating systems by using the monitor and the keyboard (terminal equipment).
4.1.1 Open the Standard Input Device File
Figure 4.1 shows the scene after tty0 file has been loaded.
4.1.1.1 File_table[0] is Mounted to Filp[0] in Process 1
After the root file system is loaded, process 1 opens the standard input device file by call- ing the open function. The code is as follows: