ubuntu18.04增加自己的系统调用
PS, ubuntu安装虚拟机vm tools
sudo apt-get upgrate
sudo apt-get install open-vm-tools-desktop -y
sudo reboot
步骤(注意根目录下要有至少40G才可以进行编译内核)
我的虚拟机cpu信息如图,所以第13、14步的N都选择的是:2
- 国内镜像下载linux内核, 我下载的是5.5.11,有需要的可以自行替换, 但是下方的某些命令需要自行替换成对应的版本号。
- 将下载的文件解压
sudo mv linux-5.5.11 /usr/src将其移动到/usr/src目录下cd /usr/src/linux-5.5.11/kernel
sudo gedit sys.c编辑sys.c文件,在最后一行,在里边增加自己写的系统调用的功能。下方增加的就是输出hello world功能
asmlinkage long sys_mysyscall(void){
printk( "hello world! ");
return 0;
}
如图:
5. cd /usr/src/linux-5.5.11/arch/x86/include/asm/
sudo gedit syscalls.h 编辑syscalls.h增加函数功能声明。
asmlinkage long sys_mysyscall(void);
6. cd /usr/src/linux-5.5.11/arch/x86/entry/syscalls
sudo gedit syscall_64.tbl编辑系统调用入口文件,增加下面的内容
335 common mysyscall sys_mysyscall
7. 接下来进行编译内核,将新增的系统调用增加到内核中,下方的命令安装必要的依赖包, 注意软件源选择国内的
sudo apt-get install libncurses5-dev openssl libssl-dev
sudo apt-get install build-essential openssl
sudo apt-get install pkg-config
sudo apt-get install libc6-dev
sudo apt-get install bison
sudo apt-get install flex
sudo apt-get install libelf-dev
sudo apt-get install zlibc minizip
sudo apt-get install libidn11-dev libidn11
cd /usr/src/linux-5.5.11sudo make mrproper得到源代码后,将其净化cp /boot/config-`uname -r` ./.configsudo make menuconfig对内核选项进行配置
选择load→(.config)OK→SAVE→(.configbak)OK→EXITmake clean(不需要) 删除配置时留下的一些不用的文件.sudo make bzImage -jN编译内核,N要根据自己的cpu硬件是几核的进行确定,不能超过cpu的最大核数。核数越多越快。单核时,内核较小可以用 make zImage (15分钟)sudo make modules -jN编译模块. N同理(虚拟机双核大概3小时)sudo make INSTALL_MOD_STRIPE=1 modules_install安装模块此时/lib/modules/下应该新生成一个KERNEL_VERSION (5.5.11)目录.
sudo mkinitramfs /lib/modules/5.5.11 -o /boot/initrd.img-5.5.11-genericsudo cp /usr/src/linux-5.5.11/arch/x86/boot/bzImage /boot/vmlinuz-5.5.11-genericsudo cp /usr/src/linux-5.5.11/System.map /boot/System.map-5.5.11sudo ln -s /boot/System.map-5.5.11 /boot/System.mapsudo update-grub
sudo reboot回车之后按住shift键不动,之后会进入grub选择界面,
选择advance options
这里选择我刚编译安装的内核版本,回车启动
结果
随便选择一个文件夹建立一个测试文件test.c
#include<stdio.h>
#include<linux/kernel.h>
#include<sys/syscall.h>
#include<unistd.h>
int main()
{
long int a=syscall(335);
printf("System call sys_mysyscall return %ld\n",a);
return 0;
}
编译连接运行test.c
gcc -o a test.c
./a
dmesg
在最后即可看到输出的hello world(实际操作时,我第一遍输入命令dmesg的时候日志中并没有出来hello world,但是我想着再执行一遍./a 然后再dmesg,这一次出现了)