Linux内核加载过程通常,Linux内核是gzip加载后的一个镜像文件。引导加载程序将压缩内核复制到内存空间。内核是自解压的。运行内核。编译好的Linux内核存放在哪里?./vmlinuxelf格式未压缩的内核。arch/arm/boot/compressed/vmlinux压缩的elf格式内核。arch/arm/boot/zImage压缩内核。压缩内核(zImage)的入口/arch/arm/boot/compressed/vmlinux.lds这个文件指定了编译器的链接顺序。ENTRY(_start)压缩内核从.start部分开始执行。在/arch/arm/boot/compressed/head.S中进行如下love操作:(1)检测系统空间。(2)初始化C代码空间。(3)跳转到C代码decompress_kernel,arch/arm/boot/compressed/misc.c。解压前的串口输出包含/asm-arm/arch-s3c2410/uncompress.h中定义puts为串口输出函数。解压后程序跳转到r5:解压后内核的起始地址。启动真正的Linux内核1,入口在arch/arm/kernel/head-armv.S2,找到处理器类型__lookup_processor_type__lookup_architecture_type3,初始化页表:__creat_page_tables4,初始化C代码空间5,跳转到C代码,start_kernelARMMMU单元MMU:内存管理单元功能:虚拟地址到物理地址的映射内存访问控制通过MMU访问Cache内存MMU会先查找TLB中的虚拟地址表如果TLB中没有虚拟地址表项,则硬件从主内存在转换表中获取转换和访问权限。ARM的MMU访问原理ARM的MMU页表格式MMU支持基于section或page的内存访问。Section:1MBmemoryblockHugepage:64KBmemoryblockSmallpage:4KBmemoryblockMicropage:1KBmemoryblock页表的层次主存中有两级转换页表:第一级表:存储段转换表和指向二级表的指针二级表:(1)存放大页和小页的转换表。(2)存储微页面的转换表。一级页表的地址一级页表占用16KB空间,必须16KB对齐一级描述符一级页表中的每一项都描述了其关联的1MB虚拟地址是如何映射的。段描述符Bits[1:0]描述符类型(10b表示段描述符)Bits[3:2]高速缓存(cache)和缓冲位(buffer)Bits[4]由具体实现定义Bits[8:5]16位之一控制部分的字段Bits[9]现在未使用,应为零Bits[11:10]访问控制(AP)Bits[19:12]现在未使用,应为零Bits[31:20]Sectionbase地址,高12位段形成物理地址的转换过程创建临时内核页表#4strr3,[r0],#4strr3,[r0],#4strr3,[r0],#4teqr0,r2bne1b清除主页表0x30004000-0xa0080000krnladrr2,r4@startofkernelr4=0xa0004000,r2=内核起始地址所在的1MB对齐空间,0x30000000addr3,r8,r2@flags+kernelbaser8是从处理器信息中获取的MMU页表标志,r8=0xc0e,r3=0x30000c0estrr3,[r4,r2,lsr#18]@identitymapping地址:0x300068000,值:0x30000c0eaddr0,r4,#(TEXTADDR&0xff000000)>>18@startofkernelbicr2,r3,#0x00f00000strr2,[r0]@PAGE_OFFSET+0MBaddr0,r0,#(TEXTADDR&0x00f00000)>>18strr3,[r0],#4@KERNEL+0...映射表内容的映射结果进入C代码init/main.c中的start_kernel函数,进入Linux内核代码。printk函数重新初始化页表,初始化中断,trap_init设置系统定时器,console...创建内核进程init
