在ARM Linux核心中增加一個新的系統呼叫
阿新 • • 發佈:2019-02-06
實驗平臺核心版本為4.0-rc1,增加的系統呼叫僅僅是簡單列印一個Hello World,最後我們在使用者空間用swi指令驗證。涉及到的改動如下:
1. 在核心中增加檔案arch/arm/kernel/mysyscall.c,這個檔案實現新的列印Hello World的系統呼叫。
#include <linux/printk.h>
void sys_helloworld(void)
{
printk("hello world\n");
}
修改arch/arm/kernel下的Makefile編入該檔案:
--- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile @@ -18,7 +18,7 @@ CFLAGS_REMOVE_return_address.o = -pg obj-y := elf.o entry-common.o irq.o opcodes.o \ process.o ptrace.o return_address.o \ setup.o signal.o sigreturn_codes.o \ - stacktrace.o sys_arm.o time.o traps.o + stacktrace.o sys_arm.o time.o traps.o mysyscall.o obj-$(CONFIG_ATAGS) += atags_parse.o obj-$(CONFIG_ATAGS_PROC) += atags_proc.o
2. 將sys_helloworld加入syscall的表,並修正syscall的數量:
數量修正,注意不是加1,而是加4,這個主要是因為padding對齊的原因。
--- a/arch/arm/include/asm/unistd.h +++ b/arch/arm/include/asm/unistd.h @@ -19,7 +19,7 @@ * This may need to be greater than __NR_last_syscall+1 in order to * account for the padding in the syscall table */ -#define __NR_syscalls (388) +#define __NR_syscalls (392) /* * *NOTE*: This is a ghost syscall private to the kernel. Only the
把sys_helloworld函式指標填入arch/arm/kernel/calls.S
--- a/arch/arm/kernel/calls.S +++ b/arch/arm/kernel/calls.S @@ -397,6 +397,7 @@ /* 385 */ CALL(sys_memfd_create) CALL(sys_bpf) CALL(sys_execveat) + CALL(sys_helloworld) #ifndef syscalls_counted .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls #define syscalls_counted
編譯核心時候,使能OABI的相容:
重新編譯核心後,寫應用程式來驗證這個系統呼叫。
3. 應用程式驗證,OABI和EABI兩種方式:
程式如下:
#include <stdio.h>
#define sys_oabi_hello() __asm__ __volatile__ ("swi 0x900000+388\n\t")
#define sys_eabi_hello() __asm__ __volatile__ ("mov r7,#388\n\t" "swi 0\n\t" )
void main(void)
{
printf("start hello\n");
sys_oabi_hello();
sys_eabi_hello();
printf("end hello\n");
}
OABI方式下,系統呼叫方式是“swi 0x900000+388”,EABI則是把388填入r7,之後發“swi 0"。
關於OABI和EABI的區別,可以在PC上執行man syscall,得到答案如下:
arch/ABI instruction syscall # retval Notes
───────────────────────────────────────────────────────────────────────────────────
arm/OABI swi NR - a1 NR is syscall #
arm/EABI swi 0x0 r7 r0