济南网站推广,网站模板大小,炉火建站,德保网站建设Linux内核加载过程通常#xff0c;Linux内核都是经过gzip加载过之后的映像文件。bootloader复制压缩内核到内存空间。内核自解压。运行内核。编译完成的Linux内核存放在哪里#xff1f;./vmlinux elf格式未压缩内核。arch/arm/boot/compressed/vmlinux 压缩以后的elf格… Linux内核加载过程通常Linux内核都是经过gzip加载过之后的映像文件。bootloader复制压缩内核到内存空间。内核自解压。运行内核。编译完成的Linux内核存放在哪里./vmlinux elf格式未压缩内核。arch/arm/boot/compressed/vmlinux 压缩以后的elf格式内核。arch/arm/boot/zImage 压缩内核。压缩内核zImage的入口/arch/arm/boot/compressed/vmlinux.lds 该文件为编译器指定link顺序。ENTRY(_start) 压缩内核从.start段开始执行。在/arch/arm/boot/compressed/head.S中执行以下爱操作 1检测系统空间。 2初始化C代码空间。 3跳转到C代码decompress_kernel arch/arm/boot/compressed/misc.c中。解压之前的串口输出include/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_kernelARM的MMU单元MMU内存管理单元作用虚拟地址到物理地址的映射存储器访问权限控制Cache通过MMU的访存MMU会先查找TLB中的虚拟地址表如果TLB中没有虚拟地址的入口硬件从主存储器中的转换表中获取转换与访问权限。ARM的MMU访存原理ARM的MMU页表格式MMU支持基于节或者页的存储器访问。节1MB的存储器块大页64KB的存储器块小页4KB的存储器块微页1KB的存储器块页表的级别存在主存储器内的转换页表有两个级别第一级表存储节转换表与指向第二级表的指针第二级表1存储大页和小页的转换表。2存储微页的转换表。一级页表的地址第一级表占用空间16KB必须16KB对齐第一级描述符一级表每个入口描述了它所关联的1MB虚拟地址是如何映射的。节描述符Bits[1:0] 描述符类型10b 表示节描述符Bits[3:2] 高速缓存cache和缓冲位bufferBits[4] 由具体实现定义Bits[8:5] 控制的节的16 种域之一Bits[9] 现在没有使用应该为零Bits[11:10] 访问控制APBits[19:12] 现在没有使用应该为零Bits[31:20] 节基址形成物理地址的高12 位节的转换过程临时内核页表的创建 __create_page_tables__create_page_tables:
pgtbl r4 page table address 0x30008000-0x4000
mov r0, r4 r00x30004000
mov r3, #0
add r2, r0, #0x4000
1: str r3, [r0], #4
str r3, [r0], #4
str r3, [r0], #4
str r3, [r0], #4
teq r0, r2
bne 1b把一级页表0x30004000-0xa0080000清空krnladr r2, r4 start of kernelr40xa0004000r2 内核起始地址所在1MB对齐空间0x30000000add r3, r8, r2 flags kernel baser8 为从处理器信息中得到的MMU 页表标志r80xc0e, r30x30000c0estr r3, [r4, r2, lsr #18] identity mapping地址:0x300068000, value:0x30000c0eadd r0, r4, #(TEXTADDR 0xff000000) 18 start of kernel
bic r2, r3, #0x00f00000
str r2, [r0] PAGE_OFFSET 0MB
add r0, r0, #(TEXTADDR 0x00f00000) 18
str r3, [r0], #4 KERNEL 0MB
......映射表内容映射结果进入C代码init/main.c中的start_kernel函数进入到了Linux内核代码中。printk函数重新初始化页表初始化中断trap_init设置系统定时器、控制台…创建内核进程init推荐阅读专辑|Linux文章汇总专辑|程序人生专辑|C语言我的知识小密圈关注公众号后台回复「1024」获取学习资料网盘链接。欢迎点赞关注转发在看您的每一次鼓励我都将铭记于心~嵌入式Linux微信扫描二维码关注我的公众号