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.11
-
sudo make mrproper
得到源代码后,将其净化 -
cp /boot/config-`uname -r` ./.config
-
sudo make menuconfig
对内核选项进行配置
选择load→(.config)OK→SAVE→(.configbak)OK→EXIT -
make 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-generic
-
sudo cp /usr/src/linux-5.5.11/arch/x86/boot/bzImage /boot/vmlinuz-5.5.11-generic
-
sudo cp /usr/src/linux-5.5.11/System.map /boot/System.map-5.5.11
-
sudo ln -s /boot/System.map-5.5.11 /boot/System.map
-
sudo 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,这一次出现了)