• Add a Syscall


    Add a syscall to kernel and replace linux kernel of RPi.


    Prepare:

    1. Cross compiler
    2. Linux Kernel for RPi

    Reference:

    Official guide


    Firstly, get the latest kernel:

    git clone https://github.com/raspberrypi/linux

    Assume that the kernel directory is 'linux' and you have already installed cross-compiler tool.


    Secondly, modify the source to add a simple syscall.

    1. linux/arch/arm/kernel/sys_arm.c

    Add syscall definition.

    In order to simplify the process, we add the definition directly in the source that exists, so that we need not to modify the Makefile. And sys_arm.c is what we need.

    Add the following definition to sys_arm.c

    asmlinkage long sys_mysyscall(int num)
    {
    printk("My syscall with argument: %d
    ",num);
    return 0;
    }
    
    

    There is a second file(Call.S) in the same directory that we need to modify. But, in order to make the process more clear, we change another file first.

    2.linux/arch/arm/include/unistd.h

    Add macro define of our syscall to this file.

    In this file, __NR_SYSCALL_BASE define the base address of syscall. And we will use this macro to define the address of our own function. Like this:

    #define __NR_mysyscall (__NR_SYSCALL_BASE+223)
    

    We use the 223th address, because this address is unused.

    3.linux/arch/arm/kernel/call.S

    Bind the definition and the address of our syscall function.

    We have function definition in sys_arm.c and function address in unistd.h. Then we should tell the system, these two is associated.

    Add this line in the file:

    CALL(sys_mysyscall)
    

    Be sure that this line is added in the 223th entry.

    4. linux/include/linux/syscalls.h

    Add the declaration of the syscall.

    We must let system know 'ther is' a syscall 223. As we usually do, add the feclaration of the function to *.h:

    asmlinkage long sys_mysyscall(int num);
    

    Now the syscall is added in the linux kernel. Begin to compile the kernel.


    Compile kernel

    Personally, I create a new directory kernel-build for output.

    That is /home/darren/opt/raspberry/kernel-build. It is not necessary.

    Clean

    Firstly, clean the project.

    #Do you know that who is Mr.Proper? Ha...
    make mrproper
    

    Configure

    Secondly, configure for your Raspberry.

    There are some differences between RPi1 and RPi2. But luckily, the official offer us a template. We need not to do this by our own.

    #RPi1
    make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-
    O=/home/darren/opt/raspberry/kernel-build bcm_defconfig
    
    #RPi2
    make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-
    O=/home/darren/opt/raspberry/kernel-build bcm2709_defconfig
    

    Okay, that is so easy...

    Make

    make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-
    O=/home/darren/opt/raspberry/kernel-build -j 12
    

    Here '-j n' is the number of thread (Is it right? ). To speed up, let it be the 1.5 * the number of processors of your pc.

    And you may know the nomber of processor by

    cat /proc/cpuinfo | grep processor | wc -l 
    

    Install

    Insert the sd card to computer. You may get two directories--root and boot.

    Denote them like these two:

    /media/boot/
    /media/root/

    Then run this command:

    make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- O=/home/darren/opt/raspberry/kernel-build -j 12 INSTALL_MOD_PATH=/media/root/ modules
    
    make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- O=/home/darren/opt/raspberry/kernel-build -j 12 INSTALL_MOD_PATH=/media/root/ modules_install
    

    Your could replace the kernel.img(or kernel7.img for RPi2) with linux/arch/arm/boot/Image

    cp linux/arch/arm/boot/Image /media/boot/
    

    Reboot and all is well.


    Syscall

    Finally, write a function to call our function:

    void inline_asm(int num)
    {
        asm volatile (
            "mov r7, #223
    "     //系统调用号
            "mov r0, %[value]
    " //参数
            "svc #0
    "           //监督调用
            :: [value] "r" (num) //return 留空,并将 num 作为传入参
        );
    }
    
    int main()
    {
        int num = 10;
        syscall(223, num); //直接使用 223 号系统调用
        num = num << 2;
        inline_asm(num);
        return 0;
    }
    
    
  • 相关阅读:
    百度&高德地图小区景点边界轮廓实现
    使用Hexo & Github,搭建属于自己的博客
    网页背景图固定不动,不跟随滚动条滚动
    jQuery同步Ajax带来的UI线程阻塞问题及解决方法
    Java并发编程实战(5)- 线程生命周期
    Java并发编程实战(4)- 死锁
    Java并发编程实战(3)- 互斥锁
    Java并发编程实战(2)- Java内存模型
    Java并发编程实战(1)- 并发程序的bug源头
    软件测试待解决问题
  • 原文地址:https://www.cnblogs.com/darryo/p/Add-a-Syscall.html
Copyright © 2020-2023  润新知