1 Star 0 Fork 11

coder_lw / wiki

forked from deepinwiki / wiki 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
操作系统理论.md 4.65 KB
一键复制 编辑 原始数据 按行查看 历史
htqx 提交于 2023-06-02 11:39 . shell & libc

操作系统理论

前言

操作系统课是一门计算机专业的基础课,这门课虽然看上去有点泛泛而谈,但它涉及的知识却是计算机中比较系统和全面的基础内容。一个没有操作系统理论的程序员,或者从业人员,可能并不影响它的实际开发和工作,但是当他们回顾这门课,也能从里面获得不少真知灼见,从而扩展自己的认识和加身自己的理解。

机器启动

x86 为例。开机复位,进入 16bit 模式,cs:ip = ffff0,该地址为硬件厂家的配置的 rom 固件程序(firmware),该程序就是 bios 或者 uefi。

bios 将引导设备的 0x7c00 位置数据读取引导程序(如 grub),然后引导程序再加载系统(linux、windows 等),并最终运行系统。

qemu seabios: 开源代码 https://www.seabios.org/SeaBIOS

模拟器 qemu:

# 实验代码:curl -Lvo linux-minimal.zip 'http://box.nju.edu.cn/f/3f67e092e1ba441187d9/?dl=1'
# 制作启动映像
cd initramfs && find . -print0 | cpio --null -ov --format=newc | gzip > ../build/initramfs.cpio.gz

# 使用虚拟机启动内核和映像
qemu-system-x86_64 \
          -nographic \
          -serial mon:stdio \
          -m 128 \
          -kernel vmlinuz \
          -initrd build/initramfs.cpio.gz \
          -append "console=ttyS0 quiet acpi=off"

# qemu 调试快捷键:ctrl + a; c

# busybox 是一个单文件工具包,使用方式 busybox ls
# 创建快捷方式
for i in $(busybox --list)
do 
    busybox ln -s busybox "\bin\$i"
done

# 挂载内核信息文件系统
mkdir -p /proc
mkdir -p /sys
mount -t proc none /proc
mount -t sysfs none /sys

# 提示符
export PS1='(busybox)# '

进程

  1. spawn
  2. fork:创建进程分支(完全复制,被复制的 fork 返回 0,两个进程继续执行)
  3. execve:创建新进程
  4. exit:关闭进程
    1. atexit:退出 c 程序,负责清理
    2. _exit:退出并关闭所有线程, syscall exit_group
    3. syscall(SYS_exit,0):旧款,退出当前线程, syscall exit

内存

  1. pmap: 内存布局 /porc/$pid/maps
    1. rwxsp: 权限:读、写、执行、共享、私有
  2. vdso: virtual system calls 虚拟系统调用
    1. vvar: 系统共享变量
  3. mmap:内存映射(可实现文件的惰性加载)
    1. munmap:回收
    2. mprotect:修改权限
// 游戏修改器
FILE *fp = popen("pidof dosbox", "r");
fscanf(fp, "%d", &pid);

sprintf(buf, "/proc/%d/mem", pid);
fd = open(buf, O_RDWR);

scan(fd)
write(fd)

// 热更新
// 48 b8 ff ff ... movabs $0xfff.., %rax
// ff e0           jmpq *%rax
#define ROUNDDOWN(ptr) ((void*))(((uintptr_t)ptr & ~0xfff))
size_t pg_size = sysconf(_SC_PAGESIZE);
char* pg_boundary = ROUNDDOWN(old);
int flags = PROT_WRITE | PROT_READ | PROT_EXEC;

mprotect(pg_boundary, 2 * pg_size, flags);
// 在原函数头部插入跳转指令,跳到新函数
memcpy(old + 0, "\x48\xb8", 2);
memcpy(old + 2, &new, 8);
memcpy(old + 10, "\xff\xe0", 2);
mprotect(pg_boundary, 2 * pg_size, flags & ~PROT_WRITE);

shell

cli (command line interface)命令行和 gui(graph user interface)图形用户接口是内核的外壳(shell)。有了 shell,就可以将用户的操作,转化为机器的指令。所以 shell 也是一门编程语言。

管道:

  1. pipe():创建管道
  2. dup():复制管道
  3. close():关闭管道
  4. /dev/tty : 默认管道是当前终端

信号:

  1. signal():注册信号处理函数。系统很多异常是以信号方式通知程序来处理。

会话(session): 首先创建会话,然后会话内有进程组(process group),进程组(process group)内有 n 个进程。控制终端(controulling terminal)标记进程组是否后台执行,任何时候只有一个前台进程,信号会发送到这个进程组。

// 实验代码:curl -OvL http://jyywiki.cn/pages/OS/2022/demos/sh-xv6.c
// zig cc sh-xv6.c -o sh -nostdlib
// 注意:只能调用当前目录下的程序或给出路径来调用,因为没有 PATH 机制
// 简单的 shell
// 1. 解析命令
// 2. 系统调用

libc

libc 是 c 语言的标准库,他是很多应用程序的直接基础,因此当你实现一个 libc,就可以移植很多相关的实用程序到你的系统中去。

类型移植:

  1. stddef.h
  2. stdint.h
  3. stdbool.h
  4. float.h
  5. limits.h
  6. stdarg.h
  7. inttypes.h

系统调用封装:

文件描述符封装:

  1. stdio.h

进程状态封装:

  1. err.h

地址空间封装:

  1. malloc()
  2. free()

参考

  1. 操作系统的状态机模型 (操作系统的加载; thread-os 代码讲解) [南京大学2022操作系统-P9]https://www.bilibili.com/video/BV1yP4y1M7FE
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/coder_lw/wiki.git
git@gitee.com:coder_lw/wiki.git
coder_lw
wiki
wiki
master

搜索帮助

Bbcd6f05 5694891 0cc6727d 5694891