在开始之前,请现配置好基本的环境,请你先完成下面博客中的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即可
