linux内核添加系统调用
【安装】
在vmware虚拟机上安装旧版本的Linux遇到很多问题,记录一下。
1.安装到一半出现错误redhat7.3 file /usr/bin/anaconda,line633....什么的。
解决:旧版本linux不支持SCSI磁盘,在创建虚拟机的时候选择IDE磁盘(应该是这个原因,其他的我修改的有:勾选在磁盘上创建立即能够使用的空间,内存改为1G)
2.安装完成后,出现图形化界面。
解决:ctrl+alt+F64切换字符界面。
3.在redhat7.3里面的 /usr/src找不到kernel文件。
解决过程:
开始的时候想在网上下载,发现连wifi是个更复杂的过程,放弃。
然后准备用U盘,发现能识别但是找不到,出现“无法加载设备linux dev/sda is not a valid block device,usb_control/bulk_msg: timeout”,放弃
然后准备用vmware的共享文件夹功能,安装vmware tools的时候出现“Enter the path to the kernel header files for the 3.8.0-27-generic kernel”,原因是内核目录不同,放弃
最后下载内核文件后制作镜像,然后用cdrom挂载上去,用cp拷贝到/usr/src,然后用tar 进行解压,成功。
【修改调用】
我参考的:http://blog.chinaunix.net/uid-14735472-id-2930265.html
然后去linux官网下载了Linux的压缩包
原文:
系统实现:
这里以具体的例子来说明如何向系统中添加新的系统调用。具体实现所用的文件等可能与上面所述有点不一致,但原理是相同的。
1、实验环境:
实验的环境为Ubuntu9.10系统,内核版本为2.6.31-21-generic。添加完系统调用后的内核版本命名为2.6.31-12。
2,实验步骤:
1)下载Linux内核:在终端中输入命令$sudo apt-get install linux-source。下载后的文件默认放在目录/usr/src下。
2) 将内核代码解压缩:例如下载的内核文件为linux-source-2.6.31.tar.bz2,运行解压命令tar –jxvf linux-source-2.6.31.tar.bz2。解压出的文件夹为/usr/src/linux-source-2.6.31。如下图:
3) 修改/usr/src/linux-source-2.6.31/kernel/sys.c文件,在文件末尾增加三个系统响应函数。函数实现如下:
asmlinkage int sys_mycall(int number)
{
printk("这是我添加的第一个系统调用");
return number;
}
asmlinkage int sys_addtotal(int number)
{
int i=0,enddate=0;
printk("这是我添加的第二个系统调用");
while(i<=number)
enddate+=i++;
return enddate;
}
asmlinkage int sys_three()
{
printk("这是我添加的第三个系统调用");
return 0;
}
4)在/usr/src/linux-source-2.6.31/arch/x86/kernel/syscall_table_32.S 中添加:.long sys_mycall。
5)在 /usr/src/linux-2.6.31/arch/x86/include/asm/unistd_32.h中添加:#define __NR_mycall 序号(例如337),添加系统调用的入口参数(注意:其中会顺序定义入口参数的序号,添加的序号是在原有最大值的基础上+1);实现如下:
编译内核,命令依次如下:
首先切换到解压的内核目录下。
第一步:make mrproper //清除内核中不稳定的目标文件,附属文件及内核配置文件
第二步:make clean //清除以前生成的目标文件和其他文件
第三步:make oldconfig// 采用默认的内核配置(使用make menuconfig可以自己配置编译选项)
第四步:make bzImage //编译内核
第五步:make modules //编译模块
第六步:make modules_install// 安装模块
编译完成后,设置采用新内核启动。
我编译成功的内核版本号命名为2.6.31.12
运行命令:
cp /usr/src/linux-source-2.6.31/arch/i386/boot/
bzImage /boot/vmlinuz-2.6.31.12-mykernel(注意:2.6.31.12为你编译的内核版本。)
mkinitramfs -o initrd.img-2.6.31.12 2.6.31.12
//执行目录/usr/src/linux-source-2.6.31/下
cp /usr/src/linux-source-2.6.31/initrd.img-2.6.31.12 /boot/ initrd.img-2.6.31.12
增加引导菜单项,配置启动项文件/boot/grub/grub.cfg。添加的配置如下:
完成后执行终端命令sudo update-grub2,之后重启,终端输入uname -a检查你的内核版本是否是你编译的版本2.6.31.12 。
编写测试函数:我的测试函数如下:
/*~~~~~~~~~~~~~~~test1.c~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#include<stdio.h>
int main()
{
int tmp;
tmp=syscall(337,1);
printf("\n");
if(tmp==1)
{
printf("第1次系统调用成功!\n");
}
tmp=syscall(338,5);
printf("\n");
if(tmp==15)
{
printf("第2次系统调用成功!\n");
}
tmp=syscall(339);
printf("\n");
if(tmp==0)
{
printf("第3次系统调用成功!\n");
}
}
编译,运行。在终端输入dmesg -c可显示函数的输出内容。
----
但是我在执行的时候遇到了编译错误,于是重新直接使用包,解压后编译还是相同的错误。等待后面的检查。