微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > ARM Linux启动代码分析

ARM Linux启动代码分析

时间:11-09 来源:互联网 点击:

比较的是struct machine_desc的成员nr的值,因此不再分析。这里需要提一下的是,比如对于mini6410(tiny6410),struct machine_desc变量的定义在arch/arm/mach-s3c64xx/mach-mini6410.c文件中,如下所示:

00512 MACHINE_START(MINI6410, "MINI6410")00513     /* Maintainer: Ben Dooks  */00514     .phys_io    = S3C_PA_UART & 0xfff00,00515     .io_pg_offst    = (((u32)S3C_VA_UART) >> 18) & 0xfffc,00516     .boot_params    = S3C64XX_PA_SDRAM + 0x100,00517 00518     .init_irq    = s3c6410_init_irq,00519     .map_io        = mini6410_map_io,00520     .init_machine    = mini6410_machine_init,00521     .timer        = &s3c24xx_timer,00522 MACHINE_END

回到head.S,86、87行判断是否支持当前的机器号,不支持就跳到__error_a标号处。

88行,跳到__vet_atags,同样是在arch/arm/kernel/head-common.S中定义:

00250 __vet_atags:00251     tst    r2, #0x3            @ aligned?00252     bne    1f00253 00254     ldr    r5, [r2, #0]            @ is first tag ATAG_CORE?00255     cmp    r5, #ATAG_CORE_SIZE00256     cmpne    r5, #ATAG_CORE_SIZE_EMPTY00257     bne    1f00258     ldr    r5, [r2, #4]00259     ldr    r6, =ATAG_CORE00260     cmp    r5, r600261     bne    1f00262 00263     mov    pc, lr                @ atag pointer is ok00264 00265 1:    mov    r2, #000266     mov    pc, lr00267 ENDPROC(__vet_atags)

251行,测试r2的低2位是否为0,也即r2的值是否4字节对齐。

252行,如果r2的低2位不为0,则跳转到265行,将r2的值设为0,然后返回。

下面先看一下bootloader传递参数给内核的结构定义,在arch/arm/include/asm/setup.h文件中:

00146 struct tag {00147     struct tag_header hdr;00148     union {00149         struct tag_core        core;00150         struct tag_mem32    mem;00151         struct tag_videotext    videotext;00152         struct tag_ramdisk    ramdisk;00153         struct tag_initrd    initrd;00154         struct tag_serialnr    serialnr;00155         struct tag_revision    revision;00156         struct tag_videolfb    videolfb;00157         struct tag_cmdline    cmdline;00158 00159         /*00160          * Acorn specific00161          */00162         struct tag_acorn    acorn;00163 00164         /*00165          * DC21285 specific00166          */00167         struct tag_memclk    memclk;00168     } u;00169 };

147行,struct tag_header的定义:

24 struct tag_header {25     __u32 size;26     __u32 tag;27 };

从struct tag的定义可以知道,bootloader传递的参数有好几种类型的tag,但是内核规定第一个tag必须是ATAG_CORE类型,最后一个必须是ATAG_NONE类型,每一种类型的tag都有一个编号,例如ATAG_CORE为0x54411,ATAG_NONE为0x00。struct tag_header的tag成员就是用来描述tag的类型,而size成员用来描述整个tag的大小。每个tag连续存放。

那么标号__vet_atags的254行的意思就是获取ATAG_CORE类型tag的size成员的值赋给r5。

255行,将r5的值与ATAG_CORE_SIZE比较,ATAG_CORE_SIZE的值为((2*4 + 3*4) >> 2),即5。

256行,如果255行比较的结果不相等,那么将r5与ATAG_CORE_SIZE_EMPTY进行比较,ATAG_CORE_SIZE_EMPTY的值为((2*4) >> 2),即2。

257行,如果还是不相等,那么跳转到265行执行,同样是将r2设为0,然后返回。

258行,获取struct tag_header的tag成员,将它的值赋给r5。

259行,r6 = ATAG_CORE,即0x54411。

260行,比较r5和r6的值。

261行,如果r5和r6的值不相等则跳转到265行,如果相等则执行263行直接返回。

至此,__vet_atags标号的内容分析完毕。

回到head.S的89行,跳转到__create_page_tables标号处,在head.S里定义:

00219 __create_page_tables:00220     pgtbl    r4                @ page table address00221 00     /*00223      * Clear the 16K level 1 swapper page table00224      */00225     mov    r0, r400226     mov    r3, #000227     add    r6, r0, #0x400228 1:    str    r3, [r0], #400229     str    r3, [r0], #400230     str    r3, [r0], #400231     str    r3, [r0], #400232     teq    r0, r600233     bne    1b00234 00235     ldr    r7, [r10, #PROCINFO_MM_MMUFLAGS] @ mm_mmuflags00236 00237     /*00238      * Create identity mapping for first MB of kernel to00239      * cater for the MMU enable.  This identity mapping00240      * will be removed by paging_init().  We use our current program00241      * counter to determine corresponding section base address.00242      */00243     mov    r6, pc00244     mov    r6, r6, lsr #20            @ start of kernel section00245     orr    r3, r7, r6, lsl #20        @ flags + kernel base00246     str    r3, [r4, r6, lsl #2]        @ identity mapping00247 00248     /*00249      * Now setup the pagetables for our kernel direct00250      * mapped region.00251      */00252     add    r0, r4,  #(KERNEL_START & 0xff) >> 1800253     str    r3, [r0, #(KERNEL_START & 0x00f00) >> 18]!00254     ldr    r6, =(KERNEL_END - 1)00255     add    r0, r0, #400256     add    r6, r4, r6, lsr #1800257 1:    cmp    r0, r600258     add    r3, r3, #1 < 2000259     strls    r3, [r0], #400260     bls    1b00261 00262 #ifdef CONFIG_XIP_KERNEL00263     /*00264      * Map some ram to cover our .data and .bss areas.00265      */00266     orr    r3, r7, #(KERNEL_RAM_PADDR & 0xff)00267     .if    (KERNEL_RAM_PADDR & 0x00f00)00268     orr    r3, r3, #(KERNEL_RAM_PADDR & 0x00f00)00269     .endif00270     add    r0, r4,  #(KERNEL_RAM_VADDR & 0xff) >> 1800271     str    r3, [r0, #(KERNEL_RAM_VADDR & 0x00f00) >> 18]!00272     ldr    r6, =(_end - 1)00273     add    r0, r0, #400274     add    r6, r4, r6, lsr #1800275 1:    cmp    r0, r600276     add    r3, r3, #1 < 2000277     strls    r3, [r0], #400278     bls    1b00279 #endif00280 00281     /*00282      * Then map first 1MB of ram in case it contains our boot params.00283      */00284     add    r0, r4, #PAGE_OFFSET >> 1800285     orr    r6, r7, #(PHYS_OFFSET & 0xff)00286     .if    (PHYS_OFFSET & 0x00f00)00287     orr    r6, r6, #(PHYS_OFFSET & 0x00f00)00288     .endif00289     str    r6, [r0]00290 00291 #ifdef CONFIG_DEBUG_LL00292     ldr    r7, [r10, #PROCINFO_IO_MMUFLAGS] @ io_mmuflags00293     /*00294      * Map in IO space for serial debugging.00295      * This allows debug messages to be output00296      * via a serial console before paging_init.00297      */00298     ldr    r3, [r8, #MACHINFO_PGOFFIO]00299     add    r0, r4, r300300     rsb    r3, r3, #0x4            @ PTRS_PER_PGD*sizeof(long)00301     cmp    r3, #0x0800            @ limit to 512MB00302     movhi    r3, #0x080000303     add    r6, r0, r300304     ldr    r3, [r8, #MACHINFO_PHYSIO]00305     orr    r3, r3, r700306 1:    str    r3, [r0], #400307     add    r3, r3, #1 < 2000308     teq    r0, r600309     bne    1b00310 #if defined(CONFIG_ARCH_NETWINDER)  defined(CONFIG_ARCH_CATS)00311     /*00312      * If were using the NetWinder or CATS, we also need to map00313      * in the 16550-type serial port for the debug messages00314      */00315     add    r0, r4, #0xff >> 1800316     orr    r3, r7, #0x7c00317     str    r3, [r0]00318 #endif00319 #ifdef CONFIG_ARCH_RPC00320     /*00321      * Map in screen at 0x02 & SCREEN2_BASE00322      * Similar reasons here - for debug.  This is00323      * only for Acorn RiscPC architectures.00324      */00325     add    r0, r4, #0x02 >> 1800326     orr    r3, r7, #0x0200327     str    r3, [r0]00328     add    r0, r4, #0xd8 >> 1800329     str    r3, [r0]00330 #endif00331 #endif00332     mov    pc, lr00 ENDPROC(__create_page_tables)

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top