以前卸载笔记里的东西,现在也看不懂了,先留着备忘
/////////////linux/init.h #define __HEAD ".head.text","ax"
/////////////arch/arm/include/asm unified.h
#ifdef CONFIG_THUMB2_KERNEL
#define ARM(x...)
#define THUMB(x...) x
#define BSYM(sym) sym + 1
#else
#define ARM(x...) x
#define THUMB(x...)
#ifdef __ASSEMBLY__
#define BSYM(sym) sym
#endif
.arm
__HEAD
ENTRY(stext)
//在定义 CONFIG_THUMB2_KERNEL的情况下
THUMB(add r9, BSYM(1f)) @kernel is always entered in ARM
//获得向1的地址,如果是thumb指令则此地址加上1,说明是thumb指令,
THUMB(bx r9) //跳转到这个地址
THUMB(1:)
///////////
arch/arm/include/asm/assembler.h
#ifdef CONFIG_THUMB2_KERNEL
.macro setmode, mode, reg
mov \reg, #\mode
msr cpsr_c, \reg
.endm
#else
.macro setmode, mode, reg
msr cpsr_c, #\mode
.endm
#endif
////////////
setmode PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9 @ 确保进入管理状态,并且封装不同的模式
mrc p15,0,r9,c0,c0 //得到cpu的id r9 = cpu_id
bl __lookup_processor_type //查找cpu的类型
__lookup_processor_type 定义在head-common.S中
下面对__lookup_processor_type进行分析
linux/init.h
#define __CPUINIT .section ".cpuinit.text", "ax"
__CPUINIT
__lookup_processor_type:
addr r3, __lookup_processor_type_data, //r3是标号__lookup_processor_type_data的实际运行地址,
//定义如下,在同一个文件里面
__lookup_processor_type_data:
.long .
.long __proc_info_begin
.long __proc_info_end
.size ........
ldmia r3,{r4-r6}; r4 = __lookup_processor_type_data的连接地址,r5 = __proc_info_begin,r6 = __proc_info_end //rc
sub r3,r3,r4 //得到运行的实际地址和链接地址的偏移并且存储在r3里面
ADDR_LINK - ADDR_RUN = ADDR_OFFSET_LINK_AND_RUN
add r5,r5,r3, //得到__proc_info_begin的实际运行地址,r5
add r6, r6,r3 //得到__proc_info_end的实际运行地址 r6
1: ldmia r5 {r3,r4} ; /value,mask //得到从__pro_info_begin地址的数据,
and r4,r4,r9
tep r3,r4
beq 2f
addr r5,r5,#PROC_INFO_SIZE sizeof(proc_info_list) asm-offset.c arch/arm/kernel DEFINE(PROC_INFO_SZ,sizeof(proc_info_list))
cmp r5,r6,
blb 1b
mv r5, #0
2: move pc,lr //执行完这些后,r5是proc_info r9是cpuID
#ifndef CONFIG_XIP_KERNEL 如果没有定义,允许内核直接在rom运行,一般都选N、
addr r3 ,2f
/////////////////////////////
2: .long .
.long PAGE_OFFSET
ldmia r3,{r4-r8};
sub