Lab4_1树莓派上增加一个Linux系统调用

本文介绍如何在树莓派上修改Linux内核源码以增加一个自定义的带参数系统调用,包括下载源码、配置编译环境、内核编译及模块安装等步骤。

教程目的:

  • 修改RPi上的Linux源码,增加一个带参数的系统调用。

教程器材及软件:

  1. 树莓派的板子。
  2. SD卡(已经有镜像刷入)。
  3. 电源线及USB充电器。
  4. U盘或USB硬盘
  5. putty和psftp。
  6. 有DHCP的网线。

教程步骤:

下载源代码:

  1. mkdir rpi
    cd rpi
    git clone git://github.com/raspberrypi/firmware.git PRiFirmware #由于我是换了相同版本的内核,所以这一步是不需要的,以下都将忽略这一步。
    git clone git://github.com/raspberrypi/linux.git RpiLinux
    git clone git://github.com/raspberrypi/tools.git RpiTools
  2. 然后,就等吧。我这里下载特别慢,每秒钟5KB的样子。然后,就是等了一晚上。

获取配置文件:

  1. 登录到树莓派上,将/proc/config.gz文件拷贝到家目录下。
  2. 查看版本情况:

  3. 将树莓派上的SD拔下来,插入到电脑中的SD卡槽中,在rpi文件夹下建一个sd1目录和sd2目录。
    mkdir sd1
    mkdir sd2
  4. 接着,在/dev目录下找找sd卡的设备名。将其挂载到sd1和sd2目录上。
  5. 到sd2中找到,sd2/home/pi/config.gz文件,将其解压缩到RpiLinux文件夹中,并将名字改为.config。
    zcat sd2/home/pi/config.gz >RpiLinux/.config

添加一个系统调用:

  1. 进入到RpiLinux/arch/arm/kernel.
  2. 新建一个hello.c:
  3. #include <linux/export.h>
    #include <linux/mm.h>
    #include <linux/utsname.h>
    #include <linux/mman.h>
    #include <linux/reboot.h>
    #include <linux/prctl.h>
    #include <linux/highuid.h>
    #include <linux/fs.h>
    #include <linux/kmod.h>
    #include <linux/perf_event.h>
    #include <linux/resource.h>
    #include <linux/kernel.h>
    #include <linux/kexec.h>
    #include <linux/workqueue.h>
    #include <linux/capability.h>
    #include <linux/device.h>
    #include <linux/key.h>
    #include <linux/times.h>
    #include <linux/posix-timers.h>
    #include <linux/security.h>
    #include <linux/dcookies.h>
    #include <linux/suspend.h>
    #include <linux/tty.h>
    #include <linux/signal.h>
    #include <linux/cn_proc.h>
    #include <linux/getcpu.h>
    #include <linux/task_io_accounting_ops.h>
    #include <linux/seccomp.h>
    #include <linux/cpu.h>
    #include <linux/personality.h>
    #include <linux/ptrace.h>
    #include <linux/fs_struct.h>
    #include <linux/file.h>
    #include <linux/mount.h>
    #include <linux/gfp.h>
    #include <linux/syscore_ops.h>
    #include <linux/version.h>
    #include <linux/ctype.h>
    
    #include <linux/compat.h>
    #include <linux/syscalls.h>
    #include <linux/kprobes.h>
    #include <linux/user_namespace.h>
    
    #include <linux/kmsg_dump.h>
    /* Move somewhere else to avoid recompiling? */
    #include <generated/utsrelease.h>
    
    #include <asm/uaccess.h>
    #include <asm/io.h>
    #include <asm/unistd.h>
    
    
    void sys_my_syscall()
    {
    	printk("Hello World!\n");
    }
    
  4. 在Makefile中添加hello.o:
  5. 在call.S中添加223号中断:

编译内核:

  1. 先需要对内核配置一下:
    export CCPREFIX=../RpiTools/arm-bcm2708/arm-bcm2708hardfp-linux-gnueabi/bin/arm-bcm2708hardfp-linux-gnueabi-
    make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig
  2. 编译内核:
    make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j3
  3. 上面的-j3表示用3个线程同时进行编译,你可以增加这个数。一个建议的选择是cpu核数+1。我的机器比较差,用了30多分钟,好的机器大约只要15分钟。
  4. 编译完的内核现在还不能用要先处理一下:
  5. cd ../RpiTools/mkimage/
    ./imagetool-uncompressed.py ../../RpiLinux/arch/arm/boot/zImage

安装内核及模块:

  1. 将模块 先安装到一个临时的地方:
    cd ../..
    mkdir modules
    cd RpiLinux/
    make modules_install ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=../modules
  2. 保存原有系统的内核与模块:
    cd ../sd1
    sudo mv kernel.img kernel_old.img
    cd ../sd2
    sudo mv /lib/firmware /lib/firmware_old
    sudo mv /lib/modules /lib/modules_old
  3. 安装新的:
    cd ..
    sudo cp RpiTools/mkimage/kernel.img sd1/kernel.img
    sudo cp -r modules/lib sd2/

测试:

  1. 将SD卡插回到树莓派中,启动。
  2. 编写1.c测试:
    #define sys_hello() {__asm__ __volatile__ ("swi 0x900000+223\n\t");}while(0)
    
    #include <stdio.h>
    int main(void)
    {
        printf("start hello\n");
        sys_hello();
        printf("end hello\n");
    }
    
  3. 编译运行:

后记:

因为之前搭了一个cygwin的交叉编译环境,所以想在cygwin下编译内核。但毕竟只是虚拟的一个环境,还是有很多不一致的地方。第一个现象是特别慢,可能的原因在于cygwin所虚拟的fork比较慢,差不多编译了两个小时都没有完成。第二个遇到的情况是windows是大小写不敏感的,所以ipt_ECN.c和ipt_ecn.c它会认为是同名文件。内核中恰巧有这样的文件,单单大小写不一样,这样就导致编译内核的时候,会出现错误。后来,我通过修改文件名的方法,绕过了这个错误。但是,还是出现了其他错误,说是logo_linux_clut224.c没有依赖可以生成它,我看到makefile中有依赖说是只要有logo_linux_clut224.ppm就可以生成它。但是,结果就是make说没有。然后,这事就进行不下去了。最终,就换到了linux去做。linux下反正很简单,一步步按教程来就可以了。

参考:

http://aguegu.net/?p=1544

http://elinux.org/RPi_Kernel_Compilation

备注:

此为浙江大学计算机学院嵌入式系统课程实验报告。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值