4. Creation and Execution of Process 2 165
4.3 Load the Shell Program
4.3.4 Execute the Shell Program
4.3.4.1 Execute the First Page Program Loading by the Shell
The shell program starts to execute, while its linear address space corresponding program contents are not loading. Thus, do not exit the corresponding page. Then, produce a “page fault” interrupt. The interrupt will distribute the page by calling the “page fault” handler program and loading a page of the shell program.
The code is as follows:
//code path:mm/page.s:
_page_fault://page fault handler program entrance xchgl%eax,(%esp)
pushl%ecx pushl%edx push%ds push%es push%fs
movl $0x10,%edx mov%dx,%ds mov%dx,%es mov%dx,%fs movl%cr2,%edx
ROM BIOS and VGA
Kernel
Enable interrupt
0x00000 0x9FFFF 0xFFFFF 0x3FFFFF 0x5FFFFF 0xFFFFFF
Adjust ESP pointer
Adjust EIP pointer The page that parameters and environment variables locate
0 128 MB 192 MB 4 GB-1
Linear address space
Process status
Process 0 Process 1 Process 2
Interruptible Interruptible Ready
Current process
Figure 4.34 Adjust EIP and ESP.
Figure 4.35 shows how to produce a page fault.
The do_no_page() function starts to execute to identify the reason for the missing page; if it is the need to load program, it will try to share shell with other processes (obvi- ously, there is no process loads shell, thus, cannot share with other process, then) apply for a new page, and read the 4 KB content of the shell program from the ramdisk by calling the bread_page() function and load the memory page. The code is as follows:
Figure 4.36 shows an application of the free page.
Figure 4.37 shows an instance of loading the shell program.
Figure 4.38 shows how the loading content is tested.
pushl%edx pushl%eax testl $1,%eax jne 1f
call _do_no_page…//Call the do_no_page handler program
//code path:mm/memory.c:
void do_no_page(unsigned long error_code,unsigned long address) {
…int nr[4];
unsigned long tmp;
unsigned long page;
int block,i;
address &= 0xfffff000;
tmp = address - current->start_code;
if (!current->executable || tmp > = current->end_data) {//If it is not //loading program, it must be other reason result in page fault
get_empty_page(address); //If there is no space for push in the stack, apply the //page and then return directly
return;
}//Obviously, this is not the case now, really need to load the program if (share_page(tmp)) //Try to share the program with other process,but
//it’s impossible return;
if (!(page = get_free_page()))//Apply a new page for shell program oom();
/* remember that 1 block is used for header */
block = 1 + tmp/BLOCK_SIZE;
for (i=0 ; i<4 ; block++,i++)
nr[i] = bmap(current->executable,block);
bread_page(page,current->executable->i_dev,nr);//Read 4 logical block //content of shell
//program into memory page //After adding a page memory, the part of this page memory may outstrip //the end_data position of process
//The following is handling the beyond part of physical page i = tmp + 4096 - current->end_data;
tmp = page + 4096;
while (i-- > 0) { tmp-- ;
*(char *)tmp = 0;
}
if (put_page(page,address)) return;
free_page(page);
oom();
}
Kernel
ROM BIOS
and VGA Enable
interrupt
0x00000 0x9FFFF 0xFFFFF 0x3FFFFF 0x5FFFFF 0xFFFFFF
Page fault interrupt happens,
then page fault handling function starts to run do_no_page
Kernel data area Kernel code area
Process status
Process 0 Process 1 Process 2
Interruptible Interruptible Ready
Current process
Figure 4.35 Page fault interrupt happens.
ROM BIOS and VGA
Kernel
Enable interrupt
0x00000 0x9FFFF 0xFFFFF 0x3FFFFF 0x5FFFFF 0xFFFFFF
Apply for a free page in memory Process status
Process 0 Process 1 Process 2
Interruptible Interruptible Ready
Current process
Figure 4.36 Get the free page.
Kernel
ROM BIOS
and VGA Enable
interrupt
0x00000 0x9FFFF 0xFFFFF 0x3FFFFF 0x5FFFFF 0xFFFFFF
Load part of shell program to the page applied
Process status
Process 0 Process 1 Process 2
Interruptible Interruptible Ready
Current process
Figure 4.37 Load the shell program.
ROM BIOS and VGA
Kernel
Enable interrupt
0x00000 0x9FFFF 0xFFFFF 0x3FFFFF 0x5FFFFF 0xFFFFFF
Do not need to clear according to the detection result Process status
Process 0 Process 1 Process 2
Interruptible wait state Interruptible wait state Ready Current process
Figure 4.38 Adjust the memory according to the task_struct of process 2.
4.3.4.2 Map the Physical Address and Linear Address of the Loading Page
After loading a page shell program, the kernel will map the content of this page to the linear address space of the shell process and create the mapping management relation in the page directory table, page table, and page. The code is as follows:
Mapping of these addresses is shown in Figure 4.39.
//code path:mm/memory.c:
void do_no_page(unsigned long error_code,unsigned long address) {
……
put_page(page,address)//Map the physical address to linear address
……
}
ROM BIOS and VGA
Kernel
Enable interrupt
0x00000 0x9FFFF 0xFFFFF 0x3FFFFF 0x5FFFFF 0xFFFFFF
Page directory
0 16 32
Set page directory item The new page table of process 2
0 159 1023
0 128 MB 192 MB 4 GB-1
The page that part of shell function loaded resides
Mapping linear address and physical address
Linear address space Process status
Process 0 Process 1 Process 2
Interruptible Interruptible Ready
Current process
Figure 4.39 Mapping the linear address and physical address.