add system call to linux

添加系统系统到内核,测试环境huawei u9508手机,基于内核代码huawei u9508 kernel

  1. 修改 arch/arm/kernel/calls.S

    diff —git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S
    index 80f7896..100320f 100644
    —- a/arch/arm/kernel/calls.S
    +++ b/arch/arm/kernel/calls.S
    @@ -385,6 +385,7 @@

    CALL(sys_syncfs)
    CALL(sys_sendmmsg)
    

    / 375 / CALL(sys_setns)

    • CALL(sys_hello)

      ifndef syscalls_counted

      .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls

      define syscalls_counted

  2. 修改 include/linux/syscalls.h

    diff —git a/include/linux/syscalls.h b/include/linux/syscalls.h
    index 8c03b98..ca05033 100644
    —- a/include/linux/syscalls.h
    +++ b/include/linux/syscalls.h
    @@ -847,4 +847,5 @@ asmlinkage long sys_open_by_handle_at(int mountdirfd,

    struct file_handle __user *handle,
    int flags);
    

    asmlinkage long sys_setns(int fd, int nstype);
    +asmlinkage long sys_hello(void);

    endif

  3. 修改 arch/arm/include/asm/unistd.h

    diff —git a/arch/arm/include/asm/unistd.h b/arch/arm/include/asm/unistd.h
    index 2c04ed5..fa6cc69 100644
    —- a/arch/arm/include/asm/unistd.h
    +++ b/arch/arm/include/asm/unistd.h
    @@ -402,6 +402,7 @@

    define NR_syncfs (NR_SYSCALL_BASE+373)

    define NR_sendmmsg (NR_SYSCALL_BASE+374)

    define NR_setns (NR_SYSCALL_BASE+375)

    +#define NR_sys_hello (NR_SYSCALL_BASE+376)

    /*

    • The following SWIs are ARM private.
  4. 在kernel下添加hello目录,并添加hello.c, Makefile

    hello/
    ├── hello.c
    └── Makefile

vim hello.c

#include <linux/kernel.h>
asmlinkage long sys_hello(void) 
{
    printk("hello world\n");
    return 0;
}

vim Makefile

obj-y := hello.o
  1. 修改kernel下Makefile

    diff —git a/Makefile b/Makefile
    index 9651e1c..3e54a62 100755
    —- a/Makefile
    +++ b/Makefile
    @@ -719,7 +719,7 @@ export mod_strip_cmd

 ifeq ($(KBUILD_EXTMOD),)
-core-y         += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
+core-y         += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ hello/

 vmlinux-dirs   := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
                     $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
  1. 编译内核

    export CROSS_COMPILE=arm-linux-androideabi-
    export ARCH=arm
    make distclean
    make hisi_k3v2oem1_defconfig
    make zImage

  2. modify boot.img with our build zImage
    mkboot boot.img boot
    ….
    mkboot boot boot_new.img
    adb reboot bootloader
    fastboot flash boot boot_new.img
    fastboot reboot

  3. 测试添加的系统调用

    jni/
    ├── Android.mk
    └── sys_hello.cpp

vim sys_hello.cpp

#include <stdio.h>
#include <linux/kernel.h>
#include <sys/syscall.h>
#include <unistd.h>

#define __NR_hello 376

long hello_syscall(void)
{
    return syscall(__NR_hello);
}

int main(int argc, char **argv)
{
    long int a = hello_syscall();
    printf("System call returned %ld\n", a);
    return 0;
}

vim Android.mk

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_SRC_FILES += sys_hello.cpp

LOCAL_MODULE := hello
include $(BUILD_EXECUTABLE)

ndk-build

StaticLibrary  : libstdc++.a
Executable     : hello
Install        : hello => libs/armeabi/hello

adb push libs/armeabi/hello /data/local/tmp/
adb shell

root@android:/data/local/tmp # ./hello                                         
System call returned 0
root@android:/data/local/tmp # dmesg                                           
<4>[5494.1, hello] [ 1911.446306] hello world

以上针对arm平台添加的系统调用,若为x86平台,则需要将1,2,3步修改为x86目录下相应的文件即可;
参考: How To Add A System Call and Recompile the Linux Kernel