原创 linux内核启动解析(三)

2012-3-31 16:13 2947 8 8 分类: 消费电子

 

1.2 __lookup_machine_type()

机器类型的查找代码如下:

__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所定义的结构。

1.3 __vet_atags()

函数代码如下:

__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。

 

linux内核启动解析(四)

linux内核启动解析(五)

 

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
8
关闭 站长推荐上一条 /3 下一条