NJU操作系统(jyy OS)课程笔记-虚拟化部分
lec14 操作系统上的进程
cpu有初始pc地址->放置固件上的初始程序(固件状态机)->启动OS(os状态机)->load init程序(程序状态机), 之后OS完全把行为转交给init(进程树的root)
llm 知道存在与知道的界限正在模糊: 知道存在且合理 逐渐趋同于 能做
例如 qemu 相关的一些东西
问llm发散出的概念->知识体系的快速建立
fork? 以状态机的视角理解
经典的for fork + printf
写了个示例
#include <cstddef>
#include <cstdio>
#include <cstdlib>
#include <stdio.h>
#include <unistd.h>
#include <vector>
#include <mutex>
#include <sys/wait.h>
#include <map>
#include <string>
using namespace std;
const size_t buf_size = 1024;
const std::map<int, std::string> mode_map = {
{_IONBF, "no buffer"},
{_IOLBF, "line buffer"},
{_IOFBF, "full buffer"},
};
void test(int __modes) {
printf("test in mode %s\n", mode_map.at(__modes).c_str());
fflush(stdout);
vector<int> childs;
std::mutex mtx;
setvbuf(stdout, nullptr, __modes, 0);
for (int i = 0; i < 2; ++i) {
int pid = fork();
printf("hello from pid %d\n", pid);
if (pid > 0) {
std::lock_guard<mutex> lock(mtx);
childs.push_back(pid);
}
}
}
int main() {
// _IOLBF, _IOFBF, _IONBF
test(_IOFBF);
printf("\n");
fflush(stdout);
return 0;
}
在_IOLBF和_IONBF的情况下会出来6个hello
每次printf都直接刷新/检测到换行符刷新缓冲, fork的时候没有IO状态
而_IOFBF会有8个hello, 在fork第二次的时候会带着缓冲区(就是一段内存空间)进行fork,所以最后的4个进程每个都带着2个hello
系统里面没有魔法
fork: 把所有的知道的不知道的都复制了
“是不是这样?” -> 不知道的底层状态被复制了
execve: 重置状态机 argc, argv, envp -> main()
execve是唯一一个可以新建一个状态机的系统调用
exit?
- main return
exitlibc提供的_exit系统调用退出(== asm volatile("mov ..., %rax; syscall"))- 直接
SYSCALL
前两个在c语言的空间, 是“normal exit”
后两个不是normal的, _exit exit_group , __exit exit self
行为区别? strace
lec15 进程的地址空间
pmap
/proc/[pid]/maps
vvar(r), vdso(rx), vsyscall
os内只读的syscall -> 可以以内存的形式共享
其实只需要进程能和OS交互一些数据就行 —— why not进程写page, OS轮询?
- 在极端的时候能提高一些高优先级的进程的性能, 某篇OSDI
地址空间应该是在运行时可变的
所以我们需要一个不存在于c世界的操作(syscall)去操作地址空间 -> mmap, munmap
入侵进程的地址空间: gdb, perf
Game Genie 物理入侵地址空间
- 外接电路: 当cpu读地址a的时候读到x, 则替换为y
jyy现场演示mini CE(雾)
gdb attach到虚拟机,查找满足某个模式的内存值, 修改之
/proc/[pid]/mem 修改器 = 调试器
xdotool: cmd X11 automation tool
ydotool: better xdotool -> 按键精灵
evdev 按键显示脚本
xdotool测试vsc插件, crazy
或许不需要那么多的“魔法工具”
OS: 解放编程能力, 什么事情在OS上可以做
变速齿轮: syscall是感知时间的唯一方法
gdb 脚本之中, 在gettimeofday打断点, 然后修改寄存器, amazing!!!
hook
patching: 整活, kpatch, 不停机更新(软件动态链接)
old func, rx -> 修改为rwx -> 修改old func为, jmp到new func
在chcore里面看看? 或许有必要研究一下gdb(attach with qemu)
lec16 syscall & unix shell
everything is a file
thing: 操作系统里面的对象
gpt时代的“编程”——自然语言?
//OS: API:
// get_object_by_name(
// "the address space file of pid=1234"
// )
文件描述符: 指向OS对象的“指针”
windows: handle(句柄)
IPC endpoints: 例子, 管道
管道是同步的
fork + pipe? 本质是"指针"的拷贝
现在两个进程都有读口和写口啦
shell, kernel 的外壳
cli: 高效简洁的编程语言
算力的提升: cli -> gui -> 自然语言
shell as pl: 基于文本替换的快速工作流搭建
job control: 类比窗口管理器的"x", 最小化
或许不需要tmux, shell就是最简单的tmux