第 8 章 syscall流程

目录

8.1. linux下异常初始化流程
8.2. syscall中断向量代码
8.3. read系统调用的实现
8.4. 如何添加系统调用
linux下在MIPS64体系中的系统调用流程的分析和处理,了解linux下系统调用的实现。

8.1. linux下异常初始化流程

首先从内核C代码入口讲起,~/repos/build_all/fp_octeon_56xx/build/linux/init/main.c

其中函数start_kernel完成了大部分的初始化工作。asmlinkage void __init start_kernel(void);它调用了trap_init来初始化系统的中断异常向量表。

trap相关的主要处理是在~/repos/build_all/fp_octeon_56xx/build/linux/arch/mips/kernel/traps.c
其中void __init trap_init(void);用来初始化向量表。

首先通过Config3只读寄存器判断是否CPU有外部中断控制器,和向量表式的中断。其中CN56XX和CN68XX是没有外部中断控制器和向量表式的中断的。它的默认异常基地址在CKSEG0 - 0xFFFF FFFF 8000 0000。但是支持MIPSr2的CPU通过Ebase寄存器确定中断向量的基地,所以真正的ebase += (read_c0_ebase() & 0x3ffff000)

然后调用per_cpu_trap_init()来初始化每个CPU的trap:
void __cpuinit per_cpu_trap_init(void);
操作Status寄存器选择64位地址和32/32 FPR寄存器模型,重启BEV和TS,设置XX位,判断是否CPU有DSP。
如果CPU支持MIPSr2,通过HWREna寄存器启用Cavium特定指令。
因为CN56XX没有外部中断控制器和向量式中断,因此不需要修改Ebase寄存器和IntCtl寄存器来修改向量基地址,和启用新的向量空间。
如果CPU支持MIPSr2,读取IntCtl.IPTI决定时钟中断号,和读取IntCtl.IPPCI决定性能计数器中断号。
初始化asid_cache版本,创建TLB Miss的处理函数,初始化当前进程的active_mm。
然后per_cpu_trap_init()返回。

之后trap_init调用set_handler()开始安装中断向量代码。
void __init set_handler(unsigned long offset, void *addr, unsigned long size);
它首先使用memcpy将指定地址和大小的中断向量表复制到以ebase为基地址offset为偏移的内存区域。同时调用local_flush_icache_range,完成icache的flush。

让我们来分析except_vec3_generic:
最大只能放128字节:
NESTED(except_vec3_generic, 0, sp)
	.set	push
	.set	noat
#if R5432_CP0_INTERRUPT_WAR
	mfc0	k0, CP0_INDEX
#endif
	mfc0	k1, CP0_CAUSE
	andi	k1, k1, 0x7c
#ifdef CONFIG_64BIT
	dsll	k1, k1, 1
#endif
	PTR_L	k0, exception_handlers(k1)
	jr	k0
	.set	pop
	END(except_vec3_generic)
读取Cause寄存器,获取异常代号到k1,然后传递给expection_handlers[ExcCode],并使用jr跳转执行。

然后调用set_except_vector来设置缺省中断向量代码。
总共有32个中断向量代码段。然后复制EJTAG debug的中断向量处理函数到最终位置。
启用cache的奇偶校验。设置数据总线指令总线错误中断,然后设置其它中断向量。

尤其8号中断是系统调用中断,使用set_except_vector(8, handle_sys)来安装.


总之通用异常向量函数在ebase+0x180,大小0x80,主要作用是查看Cause寄存器的ExcCode,调用对应的中断处理函数。各种处理函数按照顺序存放在unsigned long exception_handers[32]中,
其中
0, rollback?rollback_handle_int:handle_int
1, handle_tlbm
2, handle_tlbl
3, handle_tlbs
4, handle_adel
5, handle_ades
6, handle_ibe
7, handle_dbe
8, handle_sys
9, hanlde_bp
10, rdhwr_noopt?hanlde_ri:(cpu_has_vtag_icache?handle_ri_rdhwr_vivt:handle_ri_rdhwr))
11, handle_cpu
12, handle_ov
13, handle_tr
15, handle_fpe
22, handle_mdmx
24, handle_mcheck
25, handle_mt
26, handle_dsp