在开始之前,请现配置好基本的环境,请你先完成下面博客中的qemu和busybox部分
编译x86_64 linux并运行在qemu上
因为内核需要添加系统调用,我们需要重新编译。
本实验均在ubuntu 22.04
下进行,编译的内核版本是5.19
(低版本内核会在添加系统调用时略有不同)。
添加系统调用
linux-5.19/arch/x86/entry/syscalls/syscall_64.tbl
添加
1
| 335 64 mysetnice sys_mysetnice
|
linux-5.19/include/linux/syscalls.h
添加
1
| asmlinkage long sys_mysetnice(pid_t pid, int flag, int nicevaluse, void __user* prio, void __user* nice);
|
linux-5.19/kernel/sys.c
在最后一个#endif
前加上下面的代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| SYSCALL_DEFINE5(mysetnice, pid_t, pid, int, flag, int, nicevalue, void __user *, prio, void __user *, nice) { int cur_prio, cur_nice; struct pid *ppid; struct task_struct *pcb; int res;
ppid = find_get_pid(pid);
pcb = pid_task(ppid, PIDTYPE_PID);
if (flag == 1) { set_user_nice(pcb, nicevalue); } else if (flag != 0) { return EFAULT; }
cur_prio = task_prio(pcb); cur_nice = task_nice(pcb);
res = copy_to_user(prio, &cur_prio, sizeof(cur_prio)); res = copy_to_user(nice, &cur_nice, sizeof(cur_nice));
return 0; }
|
编译内核
内核的编译步骤与编译x86_64 linux并运行在qemu上的编译步骤相同,不予介绍。
测试添加的系统调用
qemu请务必使用带动态链接库的根文件系统
1 2 3
| $ sudo mount rootfs-lib.img rootfs-lib $ cd rootfs-lib $ sudo vim sys-demo.c
|
内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| #include "unistd.h" #include "sys/syscall.h" #include "stdio.h" #define _SYSCALL_MYSETNICE_ 335 #define EFALUT 14
int main() { int pid, flag, nicevalue; int prev_prio, prev_nice, cur_prio, cur_nice; int result;
printf("Please input variable(pid, flag, nicevalue): "); scanf("%d%d%d", &pid, &flag, &nicevalue); result = syscall(_SYSCALL_MYSETNICE_, pid, 0, nicevalue, &prev_prio, &prev_nice); if (result == EFALUT) { printf("ERROR!"); return 1; } if (flag == 1) { syscall(_SYSCALL_MYSETNICE_, pid, 1, nicevalue, &cur_prio, &cur_nice); printf("Original priority is: [%d], original nice is [%d]\n", prev_prio, prev_nice); printf("Current priority is : [%d], current nice is [%d]\n", cur_prio, cur_nice); } else if (flag == 0) { printf("Current priority is : [%d], current nice is [%d]\n", prev_prio, prev_nice); } return 0; }
|
1 2 3
| $ sudo gcc sys-demo.c -o sys-demo $ cd .. $ qemu-system-x86_64 -kernel linux-5.19/arch/x86/boot/bzImage -boot c -m 2048M -hda rootfs-lib.img -append "root=/dev/sda rw console=ttyS0,115200 acpi=off nokaslr" -serial stdio -display none
|
启动qemu之后启动sys-demo
即可