-
macOS kernel syscall hook
0x01 Before startLast year, I spent most of my time developing on macOS. However, I’m not going on anymore on it. So I decide... -
在qemu中调试RISC-V
有时通过qemu调试RISC-V指令集的程序还是挺有趣的,qemu-system-riscv32可以选择几个机型,一般使用的最多的是virt。 这是一个不对应任何真实硬件的平台,专为在虚拟机中使用而设计。virt需要使用合适的配置编译Linux... -
Linux内核设计与实现总结(3) —— 进程管理与进程调度
进程与线程
Linux内核是不区分线程与进程的,线程只是一种特殊的进程,被视为与其他进程共享地址空间的进程。与windows这种在内核专门提供线程支持的操作系统不一样。
task_struct与thread_info
task_struct(进程描述符)描述了一个进程的
所有信息
,是一个体系无关的结构,位于include/linux/sched.h
。它包含进程打开的文件、挂起的信号、进程的状态、进程的pid等。保存在tasks双向循环链表中(见上一节的链表结构体总结),因此可以从一个进程结构体出发,索引到任何其他进程结构体。目前内核中,进程描述符是用slab分配器动态生成的,task_struct有一个void *stack成员变量指向进程的内核栈。thread_info是体系相关的,位于
arch/xxx/include/asm/thread_info.h
,它存放了线程上下文,包括是否可以抢占、当前进程是属于哪一种规范的可执行程序等。早期内核配置中,在X86体系并且CONFIG_THREAD_INFO_IN_TASK没有被时,进程的thread_info存放在进程的内核栈。如果是向下增长的栈,则thread_info在栈顶低地址;向上增长的栈,thread_info还是在低地址,只不过在栈底了。因此,可以通过内核栈的地址快速获得thread_info的地址。
在thread_info中有一个struct task_struct *task变量指向task_struct。后来内核把X86的thread_info结构体中的这个task指针给去掉了(Move thread_info into task_struct),并且将thread_info放到了task_struct中。这个task指针,是为了寄存器在不够多的体系上,可以通过内核栈地址加偏移,找到thread_info,然后快速找到task_struct的。但是X86一直使用的是per_cpu的变量来保存正在使用cpu的进程的进程描述符:
1
DECLARE_PER_CPU(struct task_struct *, current_task);
所以thread_info中的task变量是可有可无的。
在进程调度时,会更新这个变量:
1
this_cpu_write(current_task, next_p);
-
Linux内核设计与实现总结(1) —— qemu内核调试环境搭建(macOS)
宿主机系统
- macOS 12.4 (x86)
安装qemu
qemu相比于vmware,简单、轻便,可以直接指定linux内核,再指定一个文件系统,即可调试。硬盘、网络设备可以后加。
首先我尝试了utmapp/UTM,这是个适用于iOS/macOS的虚拟机,基于qemu。但是在指定内核启动镜像bzImage和initramfs后,遇到了问题,一直报错:
1
The bootindex 0 has already been used
搞了一会没搞出来,索性不用UTM了,直接上qemu。
使用homebrew可以直接安装qemu。
1
➜ ~ brew install qemu
目前安装的是7.0.0_2。
安装完成之后验证一下:
1
2
3
4
5
6
7➜ ~ qemu-system-x86_64 --help
QEMU emulator version 7.0.0
Copyright (c) 2003-2022 Fabrice Bellard and the QEMU Project developers
usage: qemu-system-x86_64 [options] [disk_image]
'disk_image' is a raw hard disk image for IDE hard disk 0
....
缘起,性空。|