操作系统内核分析 实验二 Linux系统调用
准备工作
接之前的实验一:
- 为了便于复现实验结果,不出错,本文会尽可能使用终端命令。
- 之前已编译了
linux
内核和busybox
,并制作了一个根文件系统镜像。所以目前桌面存在着linux
、busybox
、rootfs
三个文件夹和一个rootfs.img
文件。 ( 若路径与我不同的,涉及路径的命令,请自行修改 ) - 本文使用
vim
文本编辑器,如若没有安装,请用下面命令安装。
sudo apt install vim
一、 实现一个新的“Hello World”系统调用。
1. 在系统调用表中添加新的系统调用编号
- 用
vim
编辑syscall_64.tbl
# 打开终端,输入下部命令。
vim ~/Desktop/linux/arch/x86/entry/syscalls/syscall_64.tbl
- 进入
vim
编辑界面后,先输入/435
,定位到系统调用表文件中 已有的系统调用编号末尾。 另可输入:set number
,设置行号。 - 输入
i
,进入编辑模式 - 再将光标移动到
435
的下面一行,输入下面的代码
436 common my_syscall __x64_sys_my_syscall
- 按
ESC
退出 编辑模式 ,进入 命令模式 ,输入:wq
保存。
2. 在实现系统调用程序文件中添加函数定义
- 用
vim
编辑sys_x86_64.c
# 打开终端,输入下部命令。
vim ~/Desktop/linux/arch/x86/kernel/sys_x86_64.c
- 进入
vim
编辑界面后,先输入G
(注意是大写),编辑界面会跳转到文件底部。 另可输入:set number
,设置行号。 - 再输入
i
,进入编辑模式。 - 在文件底部添加代码
SYSCALL_DEFINE0(my_syscall)
{
printk(KERN_INFO "Hello World!\n");
return 0;
}
- 按
ESC
退出 编辑模式 ,进入 命令模式 ,输入:wq
保存。
3. 重新编译内核,验证系统调用。
cd ~/Desktop/linux #修改当前目录
make #通过makefile,编译内核
4. 在桌面创建用户程序,调用 “Hello world” 系统调用。
- 用
vim
编辑mysyscall.c
# 打开终端,输入下部命令。
vim ~/Desktop/mysyscall.c
//进入vim编辑界面之后,输入以下代码
#include <unistd.h>
#define __NR_my_syscall 436
int main(int argc, char const *argv[])
{
long result = syscall(__NR_my_syscall);
return 0;
}
- 静态编译mysyscall.c
gcc ~/Desktop/mysyscall.c -static -o ~/Desktop/mysyscall
- 编译成功后,桌面会出现一个名为
mysyscall
可执行文件。
5. 将可执行文件mysyscall放入rootfs.img根文件系统
cd ~/Desktop
#挂载rootfs.img到rootfs
sudo mount -o loop rootfs.img rootfs
#复制 mysyscall 到rootfs文件夹
sudo cp ~/Desktop/mysyscall ~/Desktop/rootfs/
#卸载rootfs.img
sudo umount rootfs
6. 启动qemu虚拟机,运行mysyscall
sudo qemu-system-x86_64 -kernel ~/Desktop/linux/arch/x86_64/boot/bzImage -hda ~/Desktop/rootfs.img -append "console=ttyS0 root=/dev/sda" -nographic
7. 结果
在出现井号命令提示符之后,输入./mysyscall
,若出现Hello World!
则表示成功。