1. 程式人生 > >初學《Linux核心如何裝載和啟動一個可執行程式》

初學《Linux核心如何裝載和啟動一個可執行程式》

孫業毅 原創作品 轉載請註明出處

第七講 可執行程式的裝載

@2015.04

一、理論知識

Linux中,可以從c原始碼生產一個可執行程式,這其中要經過預處理、編譯和連結的過程。可以參考以下圖來理解這個過程:


其中,目標檔案中至少有編譯後的機器指令程式碼、資料,也還包括了連結時所須要的一些資訊,比如符號表、除錯資訊、字串等。這Linux中,可執行檔案的格式現在主要是ELF格式(對應於Windows中PE格式)。ELF的格式如下:


其詳細介紹,參見:http://www.muppetlabs.com/~breadbox/software/ELF.txt,這裡還有個中文版:http://www.xfocus.net/articles/200105/174.html

連結,是收集、組織程式所需的不同程式碼和資料的過程,以便程式能被裝入記憶體並被執行。連結過程分為兩步:1.空間與地址分配;2.符號解析與重定位。

在Linux中,一個程式的執行是做為一個新的程序,使用execve系統呼叫完成的。execve對應的系統呼叫是sys_execve,在其內部會解析可執行檔案格式。對應的核心程式碼,就是,在search_binary_handler中尋找符合檔案格式對應的解析模組,關鍵程式碼如下:


對於ELF檔案,retval = fmt->load_binary(bprm)實際上執行的就是load_elf_binary,其內部就是按照ELF檔案格式來載入ELF檔案的。這裡,我們也可以看到Linux是可以支援多種可執行檔案格式的,所有的格式處裡資訊用一個結構體儲存在一個連結串列中,其中的load_binary是一個函式指標,對應於該中格式的可執行檔案的載入方式;要想支援一種新的可執行檔案,只需要向連結串列中註冊一個新的format結構體就可以了,此種設計類似觀察者模式,具有很好的擴充套件性。

二、實驗過程

開啟實驗樓中的虛擬機器,在shell中依次執行以下命令,獲取本次實驗的程式碼,並編譯執行

cd LinuxKernel

rm menu -rf

git clone https://github.com/mengning/menu.git

cd menu

mv test_exec.c test.c

make rootfs 

效果如下:


關閉QEMU視窗,在shell視窗中,cd LinuxKernel回退到LinuxKernel目錄,使用下面的命令啟動核心並在CPU執行程式碼前停下以便除錯:

qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S

 

接下來,我們就可以水平分割一個新的shell窗口出來,依次使用下面的命令啟動gdb除錯

gdb

(gdb) file linux-3.18.6/vmlinux

(gdb) target remote:1234

並在系統呼叫sys_execve的入口處設定斷點

(gdb) b sys_execve

繼續執行程式,在QEMU視窗中輸入exec,系統就會停在上面設定的斷點處,如圖:


接下來我們可以單步跟蹤sys_execve的核心程式碼,也可以通過設定以下斷點

b load_elf_binary

b start_thread

來完整地跟蹤程序的建立和啟動程式碼!

三、總結

Linux系統可以通過execve API啟動一個新程序,該API又呼叫sys_execve系統呼叫,負責將新的程式程式碼和資料替換到新的程序中,開啟可執行 檔案,載入依賴的庫檔案,申請新的記憶體空間,最後執行 start_thread(regs, elf_entry, bprm->p) ,設定 new_ip, new_sp ,完成新程序的程式碼和資料替換,然後返回,接下來就是執行新的程序程式碼了。

相關推薦

Linux核心裝載啟動一個執行程式

      首先,我們需要了解,什麼是可執行程式。可執行程式是一種可以被計算機識別的程式,是原始碼經過預處理、編譯、連結等步驟後形成的程式,大體關係如下圖所示。                                      圖1.c語言程式執行流程    

初學Linux核心如何裝載啟動一個執行程式

孫業毅 原創作品 轉載請註明出處 第七講 可執行程式的裝載 @2015.04 一、理論知識 Linux中,可以從c原始碼生產一個可執行程式,這其中要經過預處理、編譯和連結的過程。可以參考以下圖來理解這個過程: 其中,目標檔案中至少有編譯後的機器指令程式碼

網易公開課《Linux核心分析》學習心得-Linux核心如何裝載啟動一個執行程式

實驗 設定斷點sys_execeve,並繼續 程式碼執行到了SyS_execve。在QEMU中執行exec,可以看到只能出現兩句,沒有完全執行完畢。 設定斷點load_elf_binary和start_thread,並執行,可以看到程式碼停在了

第7節 Linux核心如何裝載啟動一個執行程式Linux核心分析】

一、實驗要求 分析exec*函式對應的系統呼叫處理過程 二、實驗內容 理解編譯連結的過程和ELF可執行檔案格式,詳細內容參考本週第一節; 程式設計使用exec*庫函式載入一個可執行檔案,動態連結分為可執行程式裝載時動態連結和執行時動態連結,程式設

Linux核心如何裝載啟動一個執行程式

一、預備知識 1.1 編譯連結的過程 預處理:(.c---->.cpp)(注意:這裡的CPP不是C Plus Plus的意思) gcc -E -o hello.cpp hello.c -m32編譯:(.cpp---->.s彙編) gcc -x cpp-

Linux核心分析:Linux核心如何裝載啟動一個執行程式

1.編譯連結的過程和ELF可執行檔案格式 從一個原始碼檔案到一個可執行程式檔案大概要經歷如下過程: 以C程式碼為例子,有如下程式碼的一個hello.c檔案 //hello.c #include <stdio.h> int ma

7、Linux核心如何裝載啟動一個執行程式

姓名:周毅原創作品轉載請註明出處 《Linux核心分析》MOOC課程http://mooc.study.163.com/course/USTC-1000029000 一、可執行檔案的建立——預處理、編譯和連結 預處理,替換巨集定義等等:gcc -E -o

Linux核心分析之七——Linux核心如何裝載啟動一個執行程式

作者:姚開健 原創作品轉載請註明出處 《Linux核心分析》MOOC課程http://mooc.study.163.com/course/USTC-1000029000 1、ELF的檔案格式。 通常我們將程式檔案編譯後得到的目標檔案,在Linux上其格式就是ELF

GCC & ELF檔案格式 &linux核心如何載入啟動一個執行程式

1. gcc -E source_file.c-E,只執行到預編譯。直接輸出預編譯結果。2. gcc -S source_file.c    -S,只執行到原始碼到彙編程式碼的轉換,輸出彙編程式碼。3. gcc -c source_file.c-c,只執行到編譯,輸出目標檔案。4. gcc (-E/S/c/

如何將一個java程式打包成一個執行程式

可以把普通的Java程式做成真正的exe,也就是單一個exe就可以在沒有安裝JVM的機器上執行。這樣的工具常見的有JET和gcj.前者是收費的,而且做出來的exe還是需要一堆dll。推薦使用gcj.他有windows和Linux版,直接下載zip包,不需要安裝,裡面有不少例子,一些build的批處理檔案。

Linux核心編譯grub安裝注意事項(修改預設啟動項)

一般的過程不多說。 下載核心原始碼,make menuconfig , make , make modules_install, make install等一系列。 要注意的事情: 1.安裝模組時,要用特殊引數,否則編譯出來的initrd.img特別大有300M,而

Linux程序啟動過程分析do_execve(執行程式的載入執行)---Linux程序的管理與排程(十一)

execve系統呼叫 execve系統呼叫 我們前面提到了, fork, vfork等複製出來的程序是父程序的一個副本, 那麼如何我們想載入新的程式, 可以通過execve來載入和啟動新的程式。 x86架構下, 其實還實現了一個

linux核心原始碼編譯,製作啟動核心映象

第二步,解壓linux-3.2.0-rc5.tar.gz             $cd ~;             $tar -xzvf linux-3.2.0-rc5.tar.gz             $cp -r linux-3.2.0-rc5 /usr/src/kernels/         

Linux系統開機啟動過程

linu 系統初始化 mark src 初始化 text 令行 圖形界面 圖形 提起操作系統這個詞,想必大家並不陌生,有電腦端操作系統和手機端操作系統。電腦端操作系統較為熟悉的就是微軟開發的windows操作系統,還有一種就是大家稍微陌生的linux操作系統,而手機端的操作

Facebook開源Linux核心元件工具:BPF、Btrfs、Netconsd、Cgroup2、PSI、Oomd

內容摘要: 作者:Tejun Heo(Facebook的軟體工程師)和Thomas Connally。 Facebook工程文化的一個組成部分始終是我們的開發團隊致力於開發開源解決方案,以解決實際的生產問題,並應對現代大規模雲端計算的重大挑戰。今天,我們宣佈了一套解決重要

xvfb x11vnc novnc 實現在linux伺服器上單獨啟動一個firefox

安裝xvfb apt update apt install xvfb 安裝x11vnc apt install x11vnc 啟動xvfb(渲染第五屏,解析度1920x1080,顏色24) Xvfb :5 -screen 0 1920x1080x24 & &nbs

Linux核心dev_set_drvdata()dev_get_drvdata()儲存自定義結構體用法

定義位置:kernel/msm-3.18/include/linux/device.h static inline void dev_set_drvdata(struct device *dev, void *data){ dev->driver_data = data; } stat

Linux核心調整核心引數詳解

SYN COOKIE原理和Linux核心中的實現 http://www.ibm.com/developerworks/cn/linux/l-syncookie/?ca=dwcn-newsletter-linux Linux系統下的DDOS攻擊防範 http://hi.baidu.com/mo

docker用maven構建啟動一個springboot專案

maven外掛構建一個docker映象1.maven配置<plugin> <groupId>com.spotify</groupId> <artifactId>dock

Linux下安裝pyinstaller用於將py檔案打包生成一個執行檔案

(2)cd pyinstaller-2.1 執行 python setup.py install 4. 拷貝py檔案 將需打包的py檔案如test.py 拷貝到當前目錄 5. 生成可執行檔案 cd到pyinstaller目錄, 執行  python pyinstaller.py test.py可能遇到的問題1