机器类型的查找代码如下:
__lookup_machine_type:
adr r3, 3b
ldmia r3, {r4, r5, r6}
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)
我们可以看到,这和处理器类型查找函数很类似,在这里只进行简单的解说。
.long __proc_info_begin
.long __proc_info_end
3: .long .
.long __arch_info_begin
.long __arch_info_end
__arch_info_begin和__arch_info_end在arch/arm/kernel/vlinux.lds.S中定义:
__arch_info_begin = .;
*(.arch.info.init)
__arch_info_end = .;
.arch.info.init段我们可以找到在arch/arm/include/asm/mach/arch.h中有引用:
#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 \
};
我们可以在arch/arm/mach-*.c文件中找到一系列关于MACHINE_START所定义的结构。
函数代码如下:
__vet_atags:
tst r2, #0x3 @ aligned?
bne 1f
ldr r5, [r2, #0] @ is first tag ATAG_CORE?
subs r5, r5, #ATAG_CORE_SIZE
bne 1f
ldr r5, [r2, #4]
ldr r6, =ATAG_CORE
cmp r5, r6
bne 1f
mov pc, lr @ atag pointer is ok
1: mov r2, #0
mov pc, lr
ENDPROC(__vet_atags)
atag是bootloader传递给linux内核的参数列表。这个参数列表是以tag的列表形式来表示的。这个列表起始位置的tag是ATAG_CORE,用来表示这是一个有效的tag列表。如果起始tag不是ATAG_CORE,就认为bootloader没有传递tag参数给内核。以下是tag值的定义和描述,以及tag结构的定义。
Tag name |
Value |
Size |
Description |
---|---|---|---|
ATAG_NONE |
0x00000000 |
2 |
Empty tag used to end list |
ATAG_CORE |
0x54410001 |
5 (2 if empty) |
First tag used to start list |
ATAG_MEM |
0x54410002 |
4 |
Describes a physical area of memory |
ATAG_VIDEOTEXT |
0x54410003 |
5 |
Describes a VGA text display |
ATAG_RAMDISK |
0x54410004 |
5 |
Describes how the ramdisk will be used in kernel |
ATAG_INITRD2 |
0x54420005 |
4 |
Describes where the compressed ramdisk image is placed in memory |
ATAG_SERIAL |
0x54410006 |
4 |
64 bit board serial number |
ATAG_REVISION |
0x54410007 |
3 |
32 bit board revision number |
ATAG_VIDEOLFB |
0x54410008 |
8 |
Initial values for vesafb-type framebuffers |
ATAG_CMDLINE |
0x54410009 |
2 + ((length_of_cmdline + 3) / 4) |
Command line to pass to kernel |
struct tag_header {
__u32 size;
__u32 tag;
};
struct tag {
struct tag_header hdr;
union {
struct tag_core core;
struct tag_mem32 mem;
struct tag_videotext videotext;
struct tag_ramdisk ramdisk;
struct tag_initrd initrd;
struct tag_serialnr serialnr;
struct tag_revision revision;
struct tag_videolfb videolfb;
struct tag_cmdline cmdline;
struct tag_acorn acorn;
struct tag_memclk memclk;
} u;
};
__vet_atags()函数实现的就是判断r2是否是有效的tag列表指针,如果不是,就将零指针赋值给r2。
文章评论(0条评论)
登录后参与讨论