刪除記憶體後讀取 ELF 文件
我有一個支持 eMMC 的 Linux 3.10 開發設備 (Android),我試圖更好地了解 Linux 何時實際從 eMMC 讀取而不是頁面記憶體。具體來說,我對 ELF 載入過程很感興趣,我無法解釋以下結果。
我在由 init 執行且不退出的文件系統上放置了一個 ELF 文件。ELF 文件數據位於塊 0x22d930-0x22da78 中,我已修改核心以記錄對塊的任何 eMMC 讀取訪問塊。在引導過程中,日誌顯示從 eMMC 讀取了整個 ELF 文件。
mmc read block: 0x22d930, num_blocks: 0x20 mmc read block: 0x22d9f0, num_blocks: 0x88 mmc read block: 0x22d950, num_blocks: 0xa0
這對我來說很有意義,因為我希望在初始化第一個 fork/execve 是我的 ELF (0x20 + 0x88 + 0xa0 = 0x22da78 - 0x22d930) 時從 eMMC 讀取完整的 ELF。
當我刪除頁面記憶體並終止我的程序時,我的困惑就出現了。當我殺死我的程序時,init 被配置為通過另一個 fork/execve 自動重啟程序。通過刪除頁面記憶體,我希望再次從 eMMC 中讀取完整的 ELF。但是,在發出以下命令後,我只看到部分 eMMC 讀取訪問。
echo 3 > /proc/sys/vm/drop_caches && kill -9 <pid> mmc read block: 0x22d960, num_blocks: 0x10 mmc read block: 0x22d988, num_blocks: 0x8 mmc read block: 0x22d9a0, num_blocks: 0x8 mmc read block: 0x22d9c0, num_blocks: 0x40 mmc read block: 0x22da40, num_blocks: x018 mmc read block: 0x22da60, num_blocks: 0x18
我的程序使用新的 pid 成功重新啟動,但我不明白為什麼 Linux 沒有從磁碟重新讀取完整的 ELF?Linux 甚至不會重新讀取 ELF 標頭,我知道這是 execve 讀取的第一個文件。
來自我的原始程序的原始文件映射的一部分是否仍在某些記憶體/RAM 中?以下命令僅顯示我的過程。
lsof | grep <ELF name>
我將不勝感激任何幫助解釋這種行為以及我認為的邏輯有問題的地方。
問題似乎是 init 重新啟動程序和刪除頁面記憶體之間的時間。而不是發出
kill -9 <pid> && echo 3 > /proc/sys/vm/drop_caches
,正確的順序似乎如下。stop <service> echo 3 > /proc/sys/vm/drop_caches start <service>
服務停止後,文件映射不再鎖定在頁面記憶體中,現在可以刪除。當服務再次啟動時,這會強制 Linux 從磁碟重新讀取 ELF。