(2021) 18 [代碼講解] 可執行文件
南京大學操作系統課蔣炎巖老師網絡課程筆記。
視頻:https://www.bilibili.com/video/BV1HN41197Ko?p=18
講義:http://jyywiki.cn/OS/2021/slides/C8.slides#/
背景
回顧
程序 = 狀態機
- 狀態機執行 = 狀態機上的路徑
- 狀態機管理API:
- fork - 復制
- execve - 重置
- exit - 終止
狀態機 = 可執行文件
一直以來 “最神秘” 的一種文件,雙擊即可打開,這時為什么?
本次課的內容與目標
理解靜態鏈接的可執行文件
- 可執行文件的加載
- xv6加載器
可執行文件的加載
小知識:可執行文件 不等同于 ELF文件
考慮腳本文件,它也是可執行文件:
#!/bin/bash -x
echo Hello
#!/usr/bin/env python3
print('Hello')
#!./a.out
為什么是/usr/bin/env
?
-
因為
#!
需要絕對路徑 (背后是 execve) -
Shebang 究竟發生了什么?
- 不妨 strace 一下!
可以參考筆者的這篇博客:Linux中的二進制可執行文件和腳本可執行文件及Shebang。
進程(ELF)初始化
虛假的進程(ELF)初始化
execve(path, argc, envp)
:重置一個狀態機,為它傳入參數argv
和envp
,概念好理解,但究竟什么叫 傳入?
我們知道程序(狀態機)的狀態無非就是保存在寄存器或者內存中(M,G),傳入參數肯定是傳到了內存的某個地方,但究竟是哪里呢?
一定要能靜下心來讀手冊,多嘗試去靜下心來去手冊,很快就能適應它了。 RTFM
-
[System V ABI (x86-64)][http://jyywiki.cn/pages/OS/manuals/sysv-abi.pdf]
Section 3.4: Process Initialization
- 之前用 gdb 調試過 “初始狀態”
- 看到了寄存器的初始值
- 手冊完整規定了 execve 后的進程狀態
- libc 會使用它
- 根據 ABI,你可以開發自己的 libc !
- libc 會使用它
- 之前用 gdb 調試過 “初始狀態”
-
Gitlab repo
挑戰:不使用 execve 加載 ELF
理論上把可執行文件 (ELF) 指定的數據搬運到內存,就可以實現二進制文件的加載。
試一試?loader.zip: 加載靜態鏈接的 ELF (glibc)
execve 本質上是 “多余” 的,只要我們能按照手冊,把可執行文件中的內容正確地搬運到內存中,就可以替換掉execve。
- 可以用 mmap/munmap + 一小段 trampoline code 實現
- 這個系統調用可以被庫函數 (和其他系統調用) “模擬”
模擬系統調用(1):互相模擬,互相傷害
既然完全可以 “自己加載” 可執行文件。我們也可以在一個操作系統里實現另一個操作系統的 API 啊,只要能夠在本系統內模擬另一個系統的系統調用就行。指令面前系統平等 (Linux, Windows, …)。
WSL (Windows Subsystem for Linux)
- Windows 執行 ELF64; 在 Windows 中實現 Linux 系統調用
Wine (POSIX Subsystem for Windows 😂)
- 支持 Windows PE (Portable Executable) 格式
- 實現 Windows API (Overview)
模擬系統調用(2):把系統調用挪到用戶空間
操作系統可以只提供一組最基本的硬件層的抽象(如mmap)。其他的全都交給應用程序。
“微內核” (Microkernel)
- 操作系統只提供非常有限的 API 和權限管理
- 進程/線程創建和通信
- 內存映射
- 設備寄存器
- 其他都實現在用戶程序
- 例如內核里沒有文件系統
- 想打開文件?發消息給服務器吧
“外核” (Exokernel)
- 操作系統 = 庫函數
- 一個硬件上可以跑多個 libOS
灌雞湯:《操作系統》這門課究竟學什么?
相比知識點本身,獲得知識的方法和對系統的掌控力更重要。
本課程想要帶給大家的:
狀態機視角
- 程序 = 狀態機
- 操作系統 = 狀態機的虛擬化
機器永遠是對的
- 只要按照 spec 實現,就絕對能 work
- 地址空間里的每一個地址都有解釋 (vdso, vvar, …)
- CPU: 指令實現對了,仙劍就能跑、操作系統就能跑
- System-V ABI: 實現對了,不用 execve 也可以加載可執行文件
xv6 加載器
- TODO
總結
本次課內容與目標
- 理解靜態鏈接的可執行文件
- 可執行文件的加載
- xv6 加載器
Take-away messages
- RTFM; RTFSC
- 紙面上的理解都是片面的