uboot调用内核时传递的参数是 r1=Machine_ID
ENTRY(stext)
setmode PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9 @ ensure svc mode
@ and irqs disabled
mrc p15, 0, r9, c0, c0 @ get processor id
bl __lookup_processor_type @ 返回值r5=procinfo r9=cpuid
-
* r9 = cpuid
-
* Returns:
-
* r3, r4, r6 corrupted
-
* r5 = proc_info pointer in physical address space
-
* r9 = cpuid (preserved)
-
*/
-
__CPUINIT
-
__lookup_processor_type:
-
adr r3, __lookup_processor_type_data r3=下面31行代码的物理地址
-
ldmia r3, {r4 - r6} r4=下面31行的虚拟地址 r5= __proc_info_end r6=__proc_info_end
-
-
VMLINUX_SYMBOL(__proc_info_begin) = .; 属性段的开始地址 \
-
*(.proc.info.init) 此属性的结构体都在这个地址处
-
由于在配置文件中自定义了 config_cpu_arm920t =1 所以只会调用proc-arm920这个文件 即此段属性中只会有arm920t的proc结构体 \
-
VMLINUX_SYMBOL(__proc_info_end) = . 属性段的结束地址
-
-
.align
-
-
.section ".proc.info.init", #alloc, #execinstr
-
-
.type __arm920_proc_info,#object
-
__arm920_proc_info:
-
.long 0x41009200
-
.long 0xff00fff0
-
.long PMD_TYPE_SECT | \
-
PMD_SECT_BUFFERABLE | \
-
PMD_SECT_CACHEABLE | \
-
PMD_BIT4 | \
-
PMD_SECT_AP_WRITE | \
-
PMD_SECT_AP_READ
-
.long PMD_TYPE_SECT | \
-
PMD_BIT4 | \
-
PMD_SECT_AP_WRITE | \
-
PMD_SECT_AP_READ
-
b __arm920_setup
-
.long cpu_arch_name
-
.long cpu_elf_name
-
.long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB
-
.long cpu_arm920_name
-
.long arm920_processor_functions
-
.long v4wbi_tlb_fns
-
.long v4wb_user_fns
-
#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
-
.long arm920_cache_fns
-
#else
-
.long v4wt_cache_fns
-
#endif
-
.size __arm920_proc_info, . - __arm920_proc_info
-
// 处理器的信息
-
struct proc_info_list {
unsigned int cpu_val; //处理器类型
unsigned int cpu_mask; //处理器掩码
unsigned long __cpu_mm_mmu_flags; /* used by head.S */
unsigned long __cpu_io_mmu_flags; /* used by head.S */
unsigned long __cpu_flush; /* used by head.S */
const char *arch_name;
const char *elf_name;
unsigned int elf_hwcap;
const char *cpu_name;
struct processor *proc;
struct cpu_tlb_fns *tlb;
struct cpu_user_fns *user;
struct cpu_cache_fns *cache;
};
-
sub r3, r3, r4 @ get offset between virt&phy//物理地址-虚拟地址的差值
-
add r5, r5, r3 @ convert virt addresses to //对应_proc_info_begin 的物理地址
-
add r6, r6, r3 @ physical address space //对应_proc_info_end 的物理地址
-
1: ldmia r5, {r3, r4} @ //r3=value,r4= mask
-
and r4, r4, r9 @ mask wanted bits
-
teq r3, r4
-
beq 2f
-
add r5, r5, #PROC_INFO_SZ @ sizeof(proc_info_list)
-
cmp r5, r6
-
blo 1b
-
mov r5, #0 @ unknown processor
-
2: mov pc, lr
-
ENDPROC(__lookup_processor_type)
-
-
/*
-
* Look in <asm/procinfo.h> for information about the __proc_info structure.
-
*/
-
.align 2
-
.type __lookup_processor_type_data, %object
-
__lookup_processor_type_data:
-
.long .
-
.long __proc_info_begin
-
.long __proc_info_end
-
.size __lookup_processor_type_data, . - __lookup_processor_type_data
movs r10, r5 @ invalid processor (r5=0)?
THUMB( it eq ) @ force fixup-able long branch encoding
beq __error_p @ yes, error 'p'
bl __lookup_machine_type @ r5=machinfo
//查找对应的机器id
-
* r1 = machine architecture number
-
* Returns:
-
* r3, r4, r6 corrupted
-
* r5 = mach_info pointer in physical address space
-
*/
-
__lookup_machine_type:
-
adr r3, __lookup_machine_type_data //r3= __lookup_machine_type_data 的物理地址 即下面第29的物理地址
-
ldmia r3, {r4, r5, r6} r4=.long的虚拟地址(下面第29行的地址) r5=_arch_info_begin的虚拟地址 r6=arch_info_end的地址
-
-
__arch_info_begin = .; arch属性段的开始地址
-
*(.arch.info.init) arch_info的结构体 会根据CONFIG_MACH_FENG2440 CONFIG_MACH_SMDK2440是否被定义
-
来确定内核将支持那个board 通过make menuconfig 方式来选择变量 定义情况 分析Kconfig文件可知
-
__arch_info_end = .; arch属性段的结束地址
-
-
struct machine_desc {
-
unsigned int nr; /* architecture number */
-
const char *name; /* architecture name */
-
unsigned long boot_params; /* tagged list */
-
-
unsigned int nr_irqs; /* number of IRQs */
-
-
unsigned int video_start; /* start of video RAM */
-
unsigned int video_end; /* end of video RAM */
-
-
unsigned int reserve_lp0 :1; /* never has lp0 */
-
unsigned int reserve_lp1 :1; /* never has lp1 */
-
unsigned int reserve_lp2 :1; /* never has lp2 */
-
unsigned int soft_reboot :1; /* soft reboot */
-
void (*fixup)(struct machine_desc *,
-
struct tag *, char **,
-
struct meminfo *);
-
void (*reserve)(void);/* reserve mem blocks */
-
void (*map_io)(void);/* IO mapping function */
-
void (*init_early)(void);
-
void (*init_irq)(void);
-
struct sys_timer *timer; /* system tick timer */
-
void (*init_machine)(void);
-
#ifdef CONFIG_MULTI_IRQ_HANDLER
-
void (*handle_irq)(struct pt_regs *);
-
#endif
-
};
-
machine宏定义如下
-
#define MACHINE_START(_type,_name) \
-
static const struct machine_desc __mach_desc_##_type \
-
__used \
-
__attribute__((__section__(".arch.info.init"))) = { \
-
.nr = MACH_TYPE_##_type, \
-
.name = _name,
-
-
#define MACHINE_END };
以smdk2440为例
MACHINE_START(S3C2440, "SMDK2440")
.boot_params = S3C2410_SDRAM_PA + 0x100,
.init_irq = s3c24xx_init_irq,
.map_io = smdk2440_map_io,
.init_machine = smdk2440_machine_init,
.timer = &s3c24xx_timer,
MACHINE_END
宏展开后得到
static const struct machine_desc __mach_desc_S3C2440 __used __attribute__((__section__(".arch.info.init")))
= {
.nr = MACH_TYPE_S3C2440, \
.name = SMDK2440,
.init_irq = s3c24xx_init_irq,
.map_io = smdk2440_map_io,
.init_machine = smdk2440_machine_init,
.timer = &s3c24xx_timer,
};
board的结构体
-
sub r3, r3, r4 @ get offset between virt&phys
-
add r5, r5, r3 @ convert virt addresses to
-
add r6, r6, r3 @ physical address space
-
1: ldr r3, [r5, #MACHINFO_TYPE] @ get machine type
-
teq r3, r1 @ matches loader number?
-
beq 2f @ found
-
add r5, r5, #SIZEOF_MACHINE_DESC @ next machine_desc
-
cmp r5, r6
-
blo 1b
-
mov r5, #0 @ unknown machine
-
2: mov pc, lr
-
ENDPROC(__lookup_machine_type)
-
-
/*
-
* Look in arch/arm/kernel/arch.[ch] for information about the
-
* __arch_info structures.
-
*/
-
.align 2
-
.type __lookup_machine_type_data, %object
-
__lookup_machine_type_data:
-
.long .
-
.long __arch_info_begin
-
.long __arch_info_end
-
.size __lookup_machine_type_data, . - __lookup_machine_type_data
movs r8, r5 @ invalid machine (r5=0)?
THUMB( it eq ) @ force fixup-able long branch encoding
beq __error_a @ yes, error 'a'
/*
* r1 = machine no, r2 = atags,
* r8 = machinfo, r9 = cpuid, r10 = procinfo
*/
bl __vet_atags
#ifdef CONFIG_SMP_ON_UP
bl __fixup_smp
#endif
bl __create_page_tables // 创建页表
ldr r13, =__mmap_switched @
address to jump to after @ mmu has been enabled
// 复制数据 清bss段 保存processor_id=cpu id 保存_machine_arch_typ=machine id 调用start_kernel
adr lr, BSYM(1f) @ return (PIC) address
ARM( add pc, r10, #PROCINFO_INITFUNC )
THUMB( add r12, r10, #PROCINFO_INITFUNC )
THUMB( mov pc, r12 )
1: b __enable_mmu
ENDPROC(stext)
.ltorg
阅读(1618) | 评论(0) | 转发(0) |