Execute the Shell Program

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

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.

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

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

(524 trang)