韦东山第10课-内核启动

韦东山第10课-内核启动_第1张图片


1 判断内核是否支持cpu,是否支持单板

u-boot/armlinux.c 的theKernel (0, bd->bi_arch_number, bd->bi_boot_params); 是uboot启动时的uboot的结束点,kernel的开始点,bd->bi_arch_number指的是支持的挡板类型。

ENTRY(stext)

msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | SVC_MODE @ ensure svc mode

@ and irqs disabled

mrc p15, 0, r9, c0, c0@ get processor id

bl __lookup_processor_type@ r5=procinfo r9=cpuid

movs r10, r5@ invalid processor (r5=0)?

beq __error_p@ yes, error 'p'

bl __lookup_machine_type@ r5=machinfo

movs r8, r5@ invalid machine (r5=0)?

beq __error_a@ yes, error 'a'

bl __create_page_tables

__lookup_processor_type  是否支持该cpu

__lookup_machine_type  是否支持该单板

gd->bd->bi_arch_number = MACH_TYPE_SMDK2410;(board\smdk2410\smdk2410.c)(2410的cpu类型)

#define MACH_TYPE_SMDK2410             193  (include\asm-arm\mach-types.h) (2410的cpu类型) 在uboot中

__lookup_machine_type:

adr r3, 3b   //3b表示的是地址 (3:.long)如下

ldmia r3, {r4, r5, r6}

sub r3, r3, r4

3: .long .

.long __arch_info_begin

.long __arch_info_end

(linux\arch\arm\kernel\vmlinux.lds.S) :

         __arch_info_begin = .;

*(.arch.info.init)

__arch_info_end = .;


#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 \

};


MACHINE_START(S3C2440, "SMDK2440")

/* Maintainer: Ben Dooks */

.phys_io = S3C2410_PA_UART,

.io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,

.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


struct machine_desc {

/*

* Note! The first four elements are used

* by assembler code in head-armv.S

*/

unsigned int nr; /* architecture number*/

unsigned int phys_io; /* start of physical io*/

unsigned int io_pg_offst; /* byte offset for io 

* page tabe entry*/



const char *name; /* architecture name*/

unsigned long boot_params; /* tagged list*/



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 (*map_io)(void);/* IO mapping function*/

void (*init_irq)(void);

struct sys_timer*timer; /* system tick timer*/

void (*init_machine)(void);

};

uboot传入的参数bd->bi_arch_number正好和内核中的machine_desc类型(内核中编辑进去谁的machine_desc就表示支持哪种单板)对应。驱动内核时,内核的类型要和uboot传入的一一比较,看是否支持单板。

2 内核启动流程

1 判断是否支持内核

2 判断是否支持单板

3 建立页表,

4 启动mmu 因为原来uboot的地址和单板实际地址不一样要地址映射

5 跳到start_kernel

arch/arm/kernel/head.S


start_kernel

      setup_arch                         //解析uboot传入的启动参数

      setup_command_line         //解析uboot传入的启动参数

      rest_init

           kernel_init

                prepare_namespace

                        mount_root        //挂接根文件系统

                init_post

我们的uboot,内核,文件系统是在flash里写死的那么程序怎么知道内核的地址呢。因为在程序里有boot,内核,文件系统的地址;我们烧写flash的时候是根据代码写的地址烧写的。

问:我如何查找地址表呢?

答:开机启动时,串口肯定会打印出内核的相关设置信息,如:


然后可以在源代码中查找“bootloader”字样(grep “”bootloader“” * -nR),查看在哪个文件夹中有(arch/arm/plat-s3c24xx/common_amdk.c)


韦东山第10课-内核启动_第2张图片

uboot在.arch.info.init 段处存放支持的类型,

每一个machone_desc都会被放在.arch.info.init 段处,其指的是内核支持的芯片类型,然后__lookup_processor_type函数挨着比较,没有一样的说明不支持。




你可能感兴趣的:(韦东山第10课-内核启动)