本篇基于mstar901平台。
系统调用例程(以open系统调用为例):
libc中有关系统调用
1.jb/bionic/libc/unistd/open.c
2.jb/bionic/libc/arch-arm/syscalls/__open.S
kernel中系统调用相关
3.kernel3.1.10/arch/arm/kernel/ehtry-common.S
4.kernel3.1.10/arch/arm/kernel/entry-armv.S
5.kernel3.1.10/arch/arm/kernel/entry-header.S
一、libc库添加api接口
1.定义:
jb/bionic/libc/include/fcntl.h
//add by tank
extern void hello(void);
//end tank
2.添加实现:
jb/bionic/libc/unistd/hello.c
#include <unistd.h>
#include <fcntl.h>
#include <stdarg.h>
extern void __hello(void);
void hello(void)
{
return __hello();
}
jb/bionic/libc/Android.mk
libc_common_src_files := \
$(syscall_src) \
unistd/hello.c \
3.汇编代码
jb/bionic/libc/arch-arm/syscalls/__hello.S
/* autogenerated by gensyscalls.py */
#include <machine/asm.h>
#include <sys/linux-syscalls.h>
ENTRY(__hello)
.save {r4, r7}
stmfd sp!, {r4, r7}
ldr r7, =__NR_hello
swi #0
ldmfd sp!, {r4, r7}
movs r0, r0
bxpl lr
b __set_syscall_errno
END(__hello)
如上汇编代码利用swi软中断指令,完成ARM工作模式从用户到特权的切换、也即Linux从用户态到内核态的转换。在x86体系结构中是INT $80。
原理部分见:《ARM与Linux些许问题》第三章:Linux如何从用户态进入内核态 和 《ARM与Linux些许问题》第二章:Linux操作系统与ARM工作模式
jb/bionic/libc/include/sys/linux-syscalls.h
//add by tank
#define __NR_hello (__NR_SYSCALL_BASE+376)
//end tank
jb/bionic/libc/arch-arm/syscalls.mk
#add by tank@tcl.com
syscall_src += arch-arm/syscalls/__hello.S
#end tank@tcl.com
二、给Linux内核添加系统调用函数
1.添加系统调用列表
3.1.10/arch/arm/kernel/call.S
添加如下代码:
/* add by tank*/
/* 376 */ CALL(sys_hello)
/* end tank*/
源码位置:
3.1.10/arch/arm/include/asm/unistd.h
添加如下代码:
//add by tank
#define __NR_hello (__NR_SYSCALL_BASE+376)
//end tank
2.实现自己的内核函数
创建如下:
3.1.10/arch/arm/kernel/sys_arm.c
//add by tank
asmlinkage void sys_hello(void)
{
printk("tankai hello world!!\n");
}
//end tank
三、用户空间测试程序
testhello.c
#include <fcntl.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <stdio.h>
//#define __NR_hello (__NR_SYSCALL_BASE+376)
int main(void)
{
printf("start call\n");
hello();
//syscall(__NR_hello); //系统调用jb/bionic/libc/arch-arm/bionic/syscall.S
printf("end of call\n");
return 0;
}
Android.mk
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
testhello.c
LOCAL_SHARED_LIBRARIES := \
libutils
LOCAL_MODULE:= testhello
LOCAL_MODULE_TAGS := optional
include $(BUILD_EXECUTABLE)