您好,登錄后才能下訂單哦!
本篇內容主要講解“linux怎么實現程序的執行”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“linux怎么實現程序的執行”吧!
我們先看一下這時候的內存布局。
// 缺頁處理,進程的內容還沒有加載到內存,訪問的時候導致缺頁異常
void do_no_page(unsigned long error_code,unsigned long address)
{
int nr[4];
unsigned long tmp;
unsigned long page;
int block,i;
// 取得線性地址對應頁的頁首地址,與0xfffff000即減去頁偏移
address &= 0xfffff000;
// 算出離代碼段首地址的偏移
tmp = address - current->start_code;
// tmp大于等于end_data說明是訪問堆或者棧的空間時發生的缺頁,直接申請一頁
if (!current->executable || tmp >= current->end_data) {
get_empty_page(address);
return;
}
// 是否有進程已經使用了
if (share_page(tmp))
return;
// 獲取一頁,4kb
if (!(page = get_free_page()))
oom();
/* remember that 1 block is used for header */
/*
算出要讀的硬盤塊號,但是最多讀四塊。
tmp/BLOCK_SIZE算出線性地址對應頁的
頁首地址離代碼塊距離了多少塊,然后讀取頁首
地址對應的塊號,所以需要加一。比如距離2塊的距離,則
需要讀取的塊是第三塊
*/
block = 1 + tmp/BLOCK_SIZE;
// 查找文件前4塊對應的硬盤號
for (i=0 ; i<4 ; block++,i++)
// bmap算出邏輯塊號對應的物理塊號
nr[i] = bmap(current->executable,block);
// 從硬盤讀四塊數據進來,并且復制到物理頁中
bread_page(page,current->executable->i_dev,nr);
/*
tmp是小于end_data的,因為從tmp開始加載了4kb的數據,
所以tmp+4kb(4096)后大于end_data,所以大于的部分需要清0,
i即超出的字節數
*/
i = tmp + 4096 - current->end_data;
// page是物理頁首地址,加上4kb,從后往前清0
tmp = page + 4096;
while (i-- > 0) {
tmp--;
*(char *)tmp = 0;
}
// 建立線性地址和物理地址的映射
if (put_page(page,address))
return;
// 失敗則是否剛才申請的物理頁
free_page(page);
oom();
}
我們發現缺頁中斷有一句代碼是
// 算出離代碼段首地址的偏移
tmp = address - current->start_code
start_code的值就是cs對應的基地址。即進程號*64MB。address就是剛才我們通過cs:eip算出來的值。兩個相減得到線性地址離代碼段基址的距離,即硬盤中,在代碼section中的偏移。然后算出這個偏移在硬盤中相對代碼section首地址塊偏移。因為代碼塊不是可執行文件的第一塊。所以還需要做一個處理。
/* remember that 1 block is used for header */
/*
算出要讀的硬盤塊號,但是最多讀四塊。
tmp/BLOCK_SIZE算出線性地址對應頁的
頁首地址離代碼塊距離了多少塊,然后讀取頁首
地址對應的塊號,所以需要加一。比如距離2塊的距離,則
需要讀取的塊是第三塊
*/
block = 1 + tmp/BLOCK_SIZE;
就是加上可執行文件頭占據的那一塊,這樣就得出了cs:eip在硬盤中絕對偏移,最后把這塊數據讀進來。并且建立線性地址到物理地址的映射。然后重新執行cs:eip對應的指令,這時候就能找到對應的指令執行了。同理,當我們通過ds訪問數據段的時候也是這樣,在指令里,訪問數據的時候,用的地址是相對數據段的偏移,通過地址的轉換,會落到數據段對應的線性地址里。然后通過缺頁中斷加載進來。堆和棧缺頁中斷時候直接分配一頁物理內存就行。因為他的數據不在硬盤里。
到此,相信大家對“linux怎么實現程序的執行”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。