本文基于mstar801平台Linux2.6.35.11内核。
一、Linux从用户态切换到内核态的方法有哪些?
大体分为两种;主动式和被动式。
1.被动式:就是Linux在用户态(ARM在用户模式)工作,没有主动发起请求、而被动地进入内核态;包括硬件中断和程序异常。
2.主动式:就是Linux在用户态(ARM在用户模式)工作,通过发起用户态程序发起命令请求、ARM响应进入特权模式进而Linux切入内核态;就是系统调用。
二、分析上述两种切换的原理
1.被动式原理:当硬件中断过来时,通过硬件直接给CPSR置位、ARM进入IRQ模式、Linux系统进入内核态;或者用户态代码出现异常、硬件也自动完成上述工作。
2.主动式原理:即软中断,Linux内核给用户空间开放了一个可以直接操作硬件寄存器进而引发中断的机制——系统调用。当用户态调用系统调用函数时,相应的硬件被置位引发中断、导致ARM工作模式的切换(进入IRQ模式),进而Linux进入内核态。
三、系统调用原理
例如,在用户空间libc库中有对系统调用getuid()函数的定义和实现:
#include <unistd.h> int getuid(void){ long __res; __asm__ volatile("SWI") //x86上是int $0x80 : "=a" (__res) : "" (_NR_getuid); __syscall_return(int,__res); }
头文件 kernel/arch/arm/include/asm/unistd.h
#define __NR_getuid (__NR_SYSCALL_BASE+ 24)
Linux用来实现系统调用异常的实际指令是SWI(x86上int $0x80),这一指令使用中断/异常向量号128将控制权移给内核。
SWI指令其实会让ARM从用户模式进入管理模式,即Linux操作系统从用户态进入内核态;此时,保存CPSR至SPSR、保存R15-PC至R14-LR,强制CPSR致ARM进入管理模式、强制R15-PC(程序计数器)从0x0000 0008处取指令、即内核系统调用处理函数vector_SWI()。见:《ARM与Linux些许问题》第一章:ARM工作模式
下篇文章将详细分析系统调用原理:《ARM与Linux些许问题》第四章:ARM平台系统调用原理分析
====================================================================================================================================