(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
- 纸面上的理解都是片面的