1 环境准备

运行系统:vmware下安装的ubuntu10.10 32bit桌面版。

编译内核版本: linux-2.6.32.63

内核目录: /home/wanchouchou/linuxKernel/linux-2.6.32.63

为了方便,使用chmod 777 -R linux-2.6.32.63/ 将所有的内核文件都改为全权限,这样就可以在非root状态修改文件进行编译了。

2 添加系统调用

首先进入linux-2.6.32.63目录下。以后的文件路径都是以此目录为“根目录”的。

2.1 在系统函数表中添加表项

进入arch/x86/kernel目录下,然后vim syscall_table_32.S,在此文件的最后一行添加自己的系统调用表项:

 .long sys_rt_tgsigqueueinfo    /* 335 */
.long sys_perf_event_open
.long sys_mycall //这是我们自己添加的表项

好了,下面开始添加系统调用号。

2.2 添加自己的系统调用号

现在进入目录 arch/x86/include/asm,该目录下有三个文件unistd_32.h, unistd_64.h, unistd.h。由于我们编译的是32位内核,所以需要在unistd_32.h中添加系统调用号。

vim unistd_32.h,在最后添加代码:

 #define __NR_perf_event_open    336
#define __NR_mycall 337 //添加的
#ifdef __KERNEL__ /* 原本为337,但是由于我们添加了一行,所以改338*/
#define NR_syscalls 338

2.3 编写自己系统调用的实现函数

由于系统调用必须编译到核心的内核镜像中去。所以我们将此函数的实现写到kernel/sys_i386_32.c中:

 //引入头文件
#include <asm/page.h>
........
//添加函数代码
asmlinkage long sys_mycall(void){
return THREAD_SIZE;
}

3 编译内核

现在就可以回到linux-2.6.32.63目录进行编译了。如果以前编译过内核,最好使用make mrproper和make clean命令来清除之前的编译残留文件。如果是第一次编译内核,那么就需要对内核的编译选项进行配置,这里推荐使用make menuconfig。如果键入该命令后提示缺少ncurses库文件的话,就使用sudo apt-get install libncurses5-dev命令安装该库。之后就可以进行menuconfig配置了,建议保持默认值即可。

一切准备就绪,键入make命令开始编译内核!现在可以泡一桶coffee来慢慢喝了,为什么是一桶?因为时间真的很长~~~

4 编译并安装内核模块

make modules ,这个相对来说要快一点。10分钟左右。然后安装内核模块: make modules_install 以及安装内核: make install

5 让新旧内核均可以加载

sudo mkinitramfs -o /book/initrd.img-2.6.32.63  //此命令会在/boot目录下生成initrd.img-2.6.32.63等文件

sudo update-initramfs -c -k 2.6.32.63              //根据/lib/modules/2.6.32.63文件进行更新。如果此命令出现FATAL: could not load /lib/modules/2.6.32.63的话,就将命令后面的2.6.32.63改为此目录下的新内核文件名即可(注意:旧内核文件名为2.6.35-22-generic)。

sudo update-grub2                                         //自动修改系统的引导配置文件,主要是更新/book/grup/grup.cfg启动文件。此命令执行完后会在grup.cfg中添加新内核的启动项

6 进入grup选择需要启动的内核

在ubuntu10.10默认grup菜单是不会显示的,也就是说无法选择启动的内核。要想显示的话,需要按照如下步骤进行操作:

1、把/etc/default/grub文件中的GRUB_HIDDEN_TIMEOUT=0改为大于0的数字,比如4;

2、把/etc/grub.d/30_os-prober文件中所有的set timeout=0中的0改为10.仔细找,不要漏过了;

3、上述修改完成后,执行命令更新grup2: sudo update-grub  //更新/boot/grub/grub.cfg文件

7 重启

reboot。这时候在启动的时候就会停留在grup界面了,里面有4个选项,每个内核对应2个,选择进入2.6.32.63内核。启动完成后在终端输入: uname -a 显示的就是新内核版本了。

8 验证自定义的系统调用

现在我们可以编写代码来验证自定义的系统调用是否被加入到了内核中:

 #include<sdtio.h>
#include<unistd.h>
#include<sys/syscall.h> #define SYS_mycall 337 //同我们前面定义的系统调用号相同 int main(){
long ret = ;
ret = syscall(SYS_mycall); //根据系统调用号调用对应的系统调用
printf("ThreadSize is: %ld\n", ret);
return ;
}

需要说明的是,在2.6.20以后的版本是没有以前的那些系统调用宏定义的(如_syscall0, _syscall1等),必须使用syscall来进行系统调用(可以通过man syscall获取参考信息)。同时由于是系统调用,所以需要root模式下编译、运行程序。程序运行结果: 8192。

注意,按理来说,我们是不需要自己定义SYS_mycall = 337的,但是,如果不这样的话编译的时候会提示找不到SYS_mycall,也就是说,它并没有被显示地加入到syscall.h文件中~解决办法如下:

1、修改/usr/include/asm/unistd_32.h文件,将最后的#define __NR_recvmmsg  337 改为 #define __NR_mycall   337  //貌似系统中根本就没有recvmmsg只有recvmsg~

2、修改/usr/include/bits/syscall.h文件,在文件开头位置加入代码: #define SYS_mycall   __NR_mycall   ;

这样,我们就可以直接在程序中使用SYS_mycall了。

在Linux内核中添加系统调用,并编译内核的更多相关文章

  1. 向linux内核中添加外部中断驱动模块

    本文主要介绍外部中断驱动模块的编写,包括:1.linux模块的框架及混杂设备的注册.卸载.操作函数集.2.中断的申请及释放.3.等待队列的使用.4.工作队列的使用.5.定时器的使用.6.向linux内 ...

  2. linux内核学习之二:编译内核

    在linux内核学习系列的第一课中讲述了搭建学习环境的过程(http://www.cnblogs.com/xiongyuanxiong/p/3523306.html),环境搭好后,马上就进入到下一环节 ...

  3. 42.Linux应用调试-初步制作系统调用(用户态->内核态)

    1首先来讲讲应用程序如何实现系统调用(用户态->内核态)? 我们以应用程序的write()函数为例: 1)首先用户态的write()函数会进入glibc库,里面会将write()转换为swi(S ...

  4. Linux VFS中write系统调用实现原理【转】

    转自:http://blog.chinaunix.net/uid-28362602-id-3425881.html 目录 用户空间的write函数在内核里面的服务例程为sys_write Vfs_wr ...

  5. 如何利用webmin在Linux主机中添加网站

    Linux系统因其高效稳定而受到广大用户的推崇与青睐,然后其管理的复杂性也使很多用户望而却步,动弹不得.为了降低 Linux系统的管理难度,更有效方便的使用该系统,我司所有Linux主机或VPS系统均 ...

  6. 编译linux内核以及添加系统调用的全过程

    参考链接: https://www.zybuluo.com/hakureisino/note/514321# 北京邮电大学操作系统实验: https://wenku.baidu.com/view/6d ...

  7. linux centos中添加删除修改环境变量,设置java环境变量

    前言 安装完软件必要添加环境变量.指令很少,然而长时间不写就会不自信:我写的对吗?于是百度开始,于是发现又是各有千秋.好吧,好记星不如烂笔头.当然,最重要的是,百度出来的都他妈的是如何添加环境变量,只 ...

  8. 操作系统开发系列—12.f.在内核中添加中断处理 ●

    因为CPU只有一个,同一时刻要么是客户进程在运行,要么是操作系统在运行,如果实现进程,需要一种控制权转换机制,这种机制便是中断. 要做的工作有两项:设置8259A和建立IDT. /*========= ...

  9. Linux程序设计中的curses.h编译报错,无法找到curses.h和ncurses.h

    源程序screen.c如下: #include <stdio.h> #include <term.h> #include <curses.h> #include & ...

随机推荐

  1. MySQL数据库 : 自关联,视图,事物,索引

    自关联查询(自身id关联自身id(主键),查询的时候可以逻辑分为两个表,然后分别起一个别名来区分) select * from areas as cityinner join areas as pro ...

  2. Ubuntu下安装libpcap+测试安装

    1.从ftp://ftp.gnu.org/gnu/下载flex.bison.GNU M4.libpcap安装包,具体的链接分别如下: flex下载:http://flex.sourceforge.ne ...

  3. python_字符串_常用处理

    1. 输出原序列的反向互补序列 in1 = open("brca1.fasta", "r") out1 = open("re_brca1.fasta& ...

  4. Card Hand Sorting 18中南多校第一场C题

    一.题意 随机给你一堆牌(标准扑克牌),之后让你按照: 第一优先规则:所有相同花色的在一起 第二优先规则:所有相同花色的必须按照升序或者降序排列 问,你最少要拿出多少张牌插入到其他的地方以维持这个状况 ...

  5. PHP.14-图片处理类

    图片处理类 test.php <?php include "images.class.php"; $image=new Image("./images/" ...

  6. 9.5web service基础知识

    Web服务基础 用户访问网站的基本流程 我们每天都会用web客户端上网,浏览器就是一个web客户端,例如谷歌浏览器,以及火狐浏览器等. 当我们输入www.oldboyedu.com/时候,很快就能看到 ...

  7. P1395 会议(求树的重心)

    P1395 会议 题目描述 有一个村庄居住着n个村民,有n-1条路径使得这n个村民的家联通,每条路径的长度都为1.现在村长希望在某个村民家中召开一场会议,村长希望所有村民到会议地点的距离之和最小,那么 ...

  8. jQuery上传文件控件Uploadify使用

    Uploadify是JQuery的一个上传插件,支持ajax无刷新上传,多个文件同时上传,上传进行进度显示,删除已上传文件等. 首先应下载jQuery和uploadify插件 jQuery下载地址:h ...

  9. [转]多多“亦”善:把大量内容放到一页PPT的5个技巧

    技巧一:利用灰色“隐蔽”内容 灰色有个好处:自动成为“备胎”,在“现任”被浏览后才会被注意到.所以使用灰色能够让页面内容看起来没那么多. 技巧二:对齐和亲密 这是排版的两个原则. 对齐是指对页面上的元 ...

  10. 抓包工具 - Fiddler - (二)

    <转载自 miantest> 在上一篇中介绍了Fiddler的基本使用方法.通过上一篇的操作我们可以直接抓取浏览器的数据包.但在APP测试中,我们需要抓取手机APP上的数据包,应该怎么操作 ...