目标:
修改RPi上的Linux源码,增加一个带参数的系统调用。
具体步骤:
一、下载内核代码:
我下的是3.6.y版的内核地址是:https://github.com/raspberrypi/linux/archive/rpi-3.6.y.zip
二 、解压:
| dj[email protected]:~$ unzip pri-3.6.y.zip |
三、添加系统调用
进入~/linux-rpi-3.6.y/arch/arm/kernel
建mysyscall.c
在arch/arm/kernel/calls.S中添加新的系统调,新的系统调 号0x900000+379
修改arch/arm/kernel/录下的Makefile文件,在Obj-y后添加mysyscall.o
| [email protected]:~$ Zcat config.gz > .config |
拷贝树莓派/proc/config.gz到linux-rpi-3.6.y根目录解压
四、编译内核
安装交叉编译器:
| [email protected]:~$ apt-get install gcc-arm-linux-gnueabi make ncurses-dev |
查看编译器路径:
| [email protected]:~/linux-rpi-3.6.y$ dpkg -L gcc-arm-linux-gnueabi |
设置环境变量 CCPREFIX指向编译器路径
| [email protected]:~/linux-rpi-3.6.y$ export CCPREFIX=/usr/bin/arm-linux-gnueabi- |
注意最后到gnueabi-不是gnueabi-gcc
配置好后用命令查看原配置
| ~/linux-rpi-3.6.y$ make ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig
|
现在可以编译了
| ~/linux-rpi-3.6.y$ make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4 |
-j4是指用4线程编译。
编译完成后 编译模块
| ~/linux-rpi-3.6.y$ make ARCH=arm CROSS_COMPILE=${CCPREFIX} modules |
完成后就要把生成img拷贝到树莓派
生成的镜像在arch/arm/boot/Image
拷贝到树莓派的启动分区(/boot)
(我直接吧树莓派的sd卡连掉电脑上。也可以用scp来拷贝)
修改文件名为My_kernel.img
修改启动配置文件config.txt 加上一句(kernel=My_kernel.img)
现在需要传输模块
创建一个临时文件夹来放模块
| [email protected]:~/mnt/linux-rpi-3.6.y$ mkdir ../temp |
设置一个环境变量TEMP指向这个临时目录
| [email protected]:~/mnt/linux-rpi-3.6.y$ export TEMP=~/mnt/temp/ |
最后在源代码目录执行
[email protected]:~/mnt/linux-rpi-3.6.y$ make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=${TEMP} modules_install
这是在临时文件夹里会生成lib目录 把它拷贝到树莓派的/目录下
查看树莓派下lib文件夹
可见修改时间位今天的。
五、重启树莓派
可以看到内核编译时间为今天的。新内核加载成功了。
六、测试系统调用
测试代码如下:
| #define sys_hello(){__asm__ __volatile__ ("swi 0x900000+379\n\t");}while(0) #include <stdio.h> int main(void) { printf("start hello\n"); sys_hello(); printf("end hello\n"); } |
其中0x900000+379是根据在Calls.S中添加系统调用的位置来确定的。
又上图看,我加的系统调用在379的位置
编译
| [email protected] ~ $ gcc test.c -o test |
运行:
因为系统调用的时候printk所以没显示。
用dmesg显示系统log
有(hello world!!!DJY!!)系统调用成功了。
浙江大学嵌入式课程非荣誉出品
转载于:https://my.oschina.net/daijy/blog/124351