os课程的视频回放:
南大操作系统课视频回放
往期南大课程笔记
本章节课程实验M1: M1: 打印进程树
jyy推荐的库
问: 怎么删除代码复制过来时候的行号?
答: vscode中Alt+shift
, 使用鼠标拖动范围即可, 再统一删除
计算机=数字电路=状态机
同时课上提到的通过非递归来实现递归可以查看博客: 非递归方法实现递归
函数是由很多个栈帧组成的, 每一个栈帧都有一个pc值, 函数调用的本质就是, 在栈顶上添加新的一帧, 该帧的pc为0; 函数的返回则是, 将栈顶"pop"掉; 函数的执行, 取栈顶上pc值对应的语句执行.
所以所谓的C语言其实就是一个状态机:
状态: 栈帧列表和全局变量组成
初始状态: main函数的第一条语句
状态迁移:
系统上只有一个进程(程序)有访问屏幕操作的权限, 所有的程序vscod, xedit都是对该程序进行send和receive.
所以所有的程序, 都是计算一个状态机, 然后执行系统调用
strace
的使用
strace ls |& grep -e read -e write
来简化strace
的结果.strace -o trace.txt your_command
可以保存strace
的结果, 同时保证you_command
的正常执strace -o trace.txt command1
strace command2 >> trace.txt 2>&1
strace command3 >> trace.txt 2>&1
# 2>&1: 表示将标准错误(文件描述符2)重定向到标准输出(文件描述符1)
命令(xxxxxxx) = -1 XXX
: "= -1"通常表示该系统调用失败, XXX表示错误码, 表示具体的错误原因:
EINVAL
: 该错误码表示传递给系统调用的参数有误ENOENT
: 该错误码表示指定的文件或目录不存在openat
: 用于打开文件或目录, 调用成功返回文件描述符
mmap
: 用于将一个文件的一部分映射到进程的地址空间, 调用成功返回映射的起始地址
execve
: 用于在新的进程中执行一个可执行文件
arch_prctl
: 用于调整进程或线程的架构相关参数
newfstatat
: 用于获取文件状态信息,
程序编译链接流程:
硬件厂商会约定好CPU Reset后的状态, 主板厂商只要提供Firmware, 主板上的固件通常被称为BIOS(基本输入/输出系统)或UEFI(统一扩展固件接口.
如今Firmware面临更多的硬件, 所以需要UEFI.
BIOS提供机制, 将程序员的代码(操作系统)载入内存
mbr.img: mbr.S
gcc -ggdb -c $<
ld mbr.o -Ttext 0x7c00
objcopy -S -O binary -j .text a.out $@
run: mbr.img
qemu-system-x86_64 $<
debug: mbr.img
qemu-system-x86_64 -s -S $< & # Run QEMU in background
gdb -x init.gdb # RTFM: gdb (1)
clean:
rm -f *.img *.o a.out
-s
: 在tcp的1234端口打开gdbserver
-S
: 不启动cpu
以hello.c
为例
NAME := hello
SRCS := hello.c
export ARCH := x86_64-qemu
# 执行make run, 会启动一个qemu的虚拟机, 通过该虚拟机来执行SRCS
include $(AM_HOME)/Makefilesole
# 虚拟机build的操作
(
cat $AM_HOME/am/src/x86/qemu/boot/bootblock.o;
head -c 1024 /dev/zero;
cat /home/ziqiang/os2023/3-Demo2/build/hello-x86_64-qemu.elf
) > /home/ziqiang/os2023/3-Demo2/build/hello-x86_64-qemu
运行的程序就称为进程
问: 什么样的指令序列可以调用c++中的虚函数.
答: (ChatGPT的答案)
C++ 中的虚函数调用是通过虚函数表(vtable)实现的。当对象被创建时,一个指向虚函数表的指针(vptr)被添加到对象的内存布局中。每个类都有自己的虚函数表,其中包含类的虚函数的地址。当调用虚函数时,程序会使用 vptr 找到正确的虚函数。
在汇编语言层面,对虚函数的调用可能涉及到加载 vptr 的值、查找虚函数表、获取函数地址并跳转到函数等操作。
应用中,关心的两种东西:
程序就是个状态机
def main():
x = sys_choose(['Head', 'Tail'])
x = x.lower()
sys_write(f'{x}\n')
上述程序的状态机如下:红字说明是系统调用,当执行write
系统调用时,程序本身的状态没有发生改变(x='head'
),圆圈是程序的状态,方框是操作系统的状态
操作系统就是状态的管理者, 本身可以容纳多个状态机
线程可以有共享的内存, 而进程只有独立的内存能够访问
系统调用——切换线程的做法:
后面就是看jyy操作的时候,太秀了55555