环境:Ubuntu 12.10     学号:SA****199 

1.更新内核:

直接安装的系统内核版本一般不是最新,用

uname -a


查看一下 自己的版本,OK,我的是:

Linux chenhao-Rev-1-0 3.5.0-31-generic #52-Ubuntu SMP Thu May 16 16:30:01 UTC 2013 i686 i686 i686 GNU/Linux


下面来手动更新内核到最新的稳定版本。

1.获取源码

http://www.kernel.org/ 上下载最新稳定内核源代码,我下载的最新稳定版为  linux-3.9.4

下载好之后,解压到 /usr/src 文件夹下,命令如下:

sudo tar -xvf linux-3.9.4.tar.xz -C /usr/src/ 

进入该文件夹,

cd linux-3.9.4/
sudo make mrproper

该命令的功能在于清除当前目录下残留的.config和.o文件,这些文件一般是以前编译时未清理而残留的。
2.配置内核

将原来的配置文件拷过来,先到usr/src/linux-3.9.4文件夹底下,
sudo cp /usr/src/linux-headers-3.5.0-27-generic/.config .config

首先进行一下配置,进入到 /usr/src//linux-3.9.4 文件夹下,执行

sudo make menuconfig

在这之前需要安装一个ncurses,这里就不再记录安装过程了~
显示出来这种结果:


选Load,然后Ok,然后Save。
3.编译和安装

这个过程请耐心等待。。。

make bzImage //生成新内核 
make modules //编译模块
make modules_install  //安装模块
make install  // 安装内核


完成之后,grub 已经自动更新,不用在去手动更新。

OK ,重启机器,进入Ubuntu ,更新的第一次加载有点慢

重启之后,我们在看一下新的版本。


更新成功~

2.添加系统调用:


什么是系统调用:

Linux内核中设置了一组用于实现各种系统功能的子程序,称为系统调用。用户可以通过系统调用命令在自己的应用程序中调用它们。从某种角度来看,系统调用和普通的函数调用非常相似。区别仅仅在令在自己的应用程序中调用它们。从某种角度来看,系统调用和普通的函数调用非常相似。区别仅仅在于,系统调用由操作系统核心提供,运行于核心态;而普通的函数调用由函数库或用户自己提供,运行于用户态。二者在使用方式上也有相似之处。Linux系统的核心部分即是Linux内核,是一系列设备的驱动程序。系统调用是Linux内核提供的功能十分强大的一系列的函数。这些函数是在内核中实现的,它们是应用程序和内核交互的接口,系统调用在Linux系统中发挥着巨大的作用,如果没有系统调用,那么应用程序就失去了内核的支持。



  Linux核心还提供了一些C语言函数库,这些库对系统调用进行了一些包装和扩展,因为这些库函数与系统调用的关系非常紧密,所以习惯上把这些函数也称为系统调用。


系统调用是如何工作的:

一般的,进程是不能访问内核的。它不能访问内核所占内存空间也不能调用内核函数。CPU硬件决定了这些(这就是为什么它被称作"保护模式")。系统调用是这些规则的一个例外。其原理是进程先用适当的值填充寄存器,然后调用一个特殊的指令,这个指令会跳到一个事先定义的内核中的一个位置(当然,这个位置是用户进程可读但是不可写的)。在Intel CPU中,这个由中断0x80实现。硬件知道一旦你跳到这个位置,你就不是在限制模式下运行的用户,而是作为操作系统的内核--所以你就可以为所欲为。
进程可以跳转到的内核位置叫做sysem_call。这个过程检查系统调用号,这个号码告诉内核进程请求哪种服务。然后,它查看系统调用表(sys_call_table)找到所调用的内核函数入口地址。接着,就调用函数,等返回后,做一些系统检查,最后返回到进程(或到其他进程,如果这个进程时间用尽)。如果你希望读这段代码,它在<内核源码目录>/kernel/entry.S,Entry(system_call)的下一行。



下面来实现一个简单的系统调用。

1)系统调用函数的实现。
添加一个系统调用我们需要在系统调用表中增加一个新的条目,然后存储新的系统调用函数的地址。
x86架构的系统调用表 在内核代码的 arch/x86/syscalls 文件夹底下,我们显示出来它的内容,并且进入
chenhao@chenhao-Rev-1-0:/usr/src/linux-3.9.4$ ls arch/x86/syscalls/
Makefile syscall_32.tbl syscall_64.tbl syscallhdr.sh syscalltbl.sh 


syscall_32.tbl 包含了 x86 32bit的系统调用 ,而syscall_64.tbl 包含了 x86 64bit的系统调用,需要根据自己使用机器的类型来向不同的表中添加系统调用。
sudo vim arch/x86/syscalls/syscall_32.tbl 

在表中添加新的系统调用:
 349 i386 kcmp sys_kcmp
 350 i386 finit_module sys_finit_module
 351 i386    lsproc          sys_lsproc// 自己添加的系统调用号码


新的系统调用的名字为 lsproc,这个时候我们已经添加了新的条目,系统调用的函数 名字叫做 sys_lsproc.在linux 内核中,系统调用的函数名称 使用 sys_syscallname 这种格式。这使得我们在浏览内核目录的时候很容易的辨别一个函数是不是系统调用函数。


OK,下一步我们来完成 我们的系统调用函数sys_lsproc,首先我们应该去声明一下函数原型,在 syscall.h中
打开该文件,

sudo vim include/linux/syscalls.h


在最后添加 函数原型:

asmlinkage int sys_lsproc(int num);


asmlinkage是个宏,使用它是为了保持参数在stack中。
#define asmlinkage CPP_ASMLINKAGE __attribute__((regparm(0)))
asmlinkage大都用在系统调用中。有一些情况下是需要明确的告诉编译器,我们是使用stack来传递参数的,比如X86中的系统调用,是先将参数压入stack以后调用sys_*函数的,所以所有的sys_*函数都有asmlinkage来告诉编译器不要使用寄存器来编译,

OK,下一步我们来定义我们自己的系统调用函数, 进入 kernel 文件夹,


chenhao@chenhao-Rev-1-0:/usr/src/linux-3.9.4/kernel$ sudo vim sys.c 

下面这一步:



asmlinkage int sys_lsproc (int num) 
{ 
    printk("Hi,I'm Chen Hao . My student No. is SA*****199~"); 
    return 1;
}




OK,下一步重新编译内核安装



Logo

更多推荐