ARM学习笔记之驱动程序篇六----系统调用

1.9 系统调用

1.9.1 系统调用概述

计算机系统的各种硬件资源是有限的,在现代多任务操作系统上同时运行的多个进程都需要访问这些资源,为了更好的管理这些资源进程是不允许直接操作的,所有对这些资源的访问都必须有操作系统控制。也就是说操作系统是使用这些资源的唯一入口,而这个入口就是操作系统提供的系统调用(System Call)。在linux中系统调用是用户空间访问内核的唯一手段,除异常和陷入外,他们是内核唯一的合法入口。

一般情况下应用程序通过应用编程接口API,而不是直接通过系统调用来编程。在Unix世界,最流行的API是基于POSIX标准的。

操作系统一般是通过中断从用户态切换到内核态。中断就是一个硬件或软件请求,要求CPU暂停当前的工作,去处理更重要的事情。比如,在x86机器上可以通过int指令进行软件中断,而在磁盘完成读写操作后会向CPU发起硬件中断。

中断有两个重要的属性,中断号和中断处理程序。中断号用来标识不同的中断,不同的中断具有不同的中断处理程序。在操作系统内核中维护着一个中断向量表(Interrupt Vector Table),这个数组存储了所有中断处理程序的地址,而中断号就是相应中断在中断向量表中的偏移量。

一般地,系统调用都是通过软件中断实现的,x86系统上的软件中断由int 0x80指令产生,而128号异常处理程序就是系统调用处理程序system_call(),它与硬件体系有关,在entry.S中用汇编写。接下来就来看一下Linux下系统调用具体的实现过程。

1.9.2 系统调用实现

在ARM系统上,通过swi(软中断指令)指令进行系统调用,系统调用有很多,通过系统调用编号来区分,进行系统调用之前,须将编号写入r7寄存器。

1,使用printk打印一条信息

   在./kernel/printk.c中添加函数sys_pk()。

/*
*创建一个新的系统调用sys_pk
*/
void sys_pk()
{
	printk("This is a new sys call!\n");
}

2,在./arch/arm/kernel/calls.S添加系统调用入口

CALL(sys_pk)

注意:不要打乱前边的顺序,将新添加的系统调用放到最后。

3 ,给系统编号

./arch/arm/include/asm/unistd.h中最后添加宏,在原有系统调用的基础上依次加1。

#define __NR_pk			(__NR_SYSCALL_BASE+370)

4,编写测试程序

void pk()
{
    __asm__ (
    "ldr r7,=363 \n"
    "swi \n"
    :
    :
    :"memory");
}
void main()
{
    pk();	
}

注意:编译时使用静态编译,因为开发板上运行的linux系统没有所需的库。 

 

 

 

你可能感兴趣的:(ARM学习笔记)