Linux中断导读之一–初始化2

继续上一篇(见 ),看一下中断向量表初始化部分:

代码在init/main.c-start_kernel/setup_arch(&command_line);

early_trap_init

调用arch/arm/kernel/traps.c中

void __init early_trap_init(void){#if defined(CONFIG_CPU_USE_DOMAINS) unsigned long vectors = CONFIG_VECTORS_BASE; //可以配置trap基地址#else unsigned long vectors = (unsigned long)vectors_page;#endif extern char __stubs_start[], __stubs_end[]; extern char __vectors_start[], __vectors_end[]; extern char __kuser_helper_start[], __kuser_helper_end[]; int kuser_sz = __kuser_helper_end – __kuser_helper_start; /* * Copy the vectors, stubs and kuser helpers (in entry-armv.S) * into the vector page, mapped at 0xffff0000, and ensure these * are visible to the instruction stream. */ //将entry-armv.s对应部分copy到该地址, memcpy((void *)vectors, __vectors_start, __vectors_end – __vectors_start); memcpy((void *)vectors + 0x200, __stubs_start, __stubs_end – __stubs_start); memcpy((void *)vectors + 0x1000 – kuser_sz, __kuser_helper_start, kuser_sz); /* * Do processor specific fixups for the kuser helpers */ kuser_get_tls_init(vectors); /* * Copy signal return handlers into the vector page, and * set sigreturn to be a pointer to these. */ memcpy((void *)(vectors + KERN_SIGRETURN_CODE – CONFIG_VECTORS_BASE), sigreturn_codes, sizeof(sigreturn_codes)); memcpy((void *)(vectors + KERN_RESTART_CODE – CONFIG_VECTORS_BASE), syscall_restart_code, sizeof(syscall_restart_code)); flush_icache_range(vectors, vectors + PAGE_SIZE); modify_domain(DOMAIN_USER, DOMAIN_CLIENT);}

#在arch/arm/kernel/entry-armv.s中__vectors_start:ARM( swi SYS_ERROR0 )THUMB( svc #0 )THUMB( nop ) //复位 W(b) vector_und + stubs_offset //未定义模式 W(ldr) pc, .LCvswi + stubs_offset //swi,系统调用进入 W(b) vector_pabt + stubs_offset //指令预取 W(b) vector_dabt + stubs_offset //data W(b) vector_addrexcptn + stubs_offset //reserve W(b) vector_irq + stubs_offset //irq W(b) vector_fiq + stubs_offset //fiq,没有用到 .globl __vectors_end__vectors_end:.equ stubs_offset, __vectors_start + 0x200 – __stubs_start

#先看宏:/** Vector stubs.** This code is copied to 0xffff0200 so we can use branches in the* vectors, rather than ldr’s. Note that this code must not* exceed 0x300 bytes.** Common stub entry macro:* Enter in IRQ mode, spsr = SVC/USR CPSR, lr = SVC/USR PC** SP points to a minimal amount of processor-private memory, the address* of which is copied into r0 for the mode specific abort handler.*/ .macro vector_stub, name, mode, correction=0 .align 5vector_\name: .if \correction sub lr, lr, #\correction .endif @ @ Save r0, lr_<exception> (parent PC) and spsr_<exception> @ (parent CPSR) @ stmia sp, {r0, lr} @ save r0, lr mrs lr, spsr str lr, [sp, #8] @ save spsr @ @ Prepare for SVC32 mode. IRQs remain disabled. @ mrs r0, cpsr eor r0, r0, #(\mode ^ SVC_MODE | PSR_ISETSTATE) msr spsr_cxsf, r0 @ @ the branch table must immediately follow this code @ and lr, lr, #0x0fTHUMB( adr r0, 1f )THUMB( ldr lr, [r0, lr, lsl #2] ) mov r0, spARM( ldr lr, [pc, lr, lsl #2] ) movs pc, lr @ branch to handler in SVC mode

,再发展下来才有了:大霞美的花卉基地和清源山的花博园。

Linux中断导读之一–初始化2

相关文章:

你感兴趣的文章:

标签云: