欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

uboot到kernel启动过程中内存布局变化、初始化

程序员文章站 2024-02-25 11:37:10
...

内核编译(make)之后会生成两个文件,一个是Image,一个是zImage,其中Image为内核映像文件,而zImage为内核的一种映像压缩文件。uImageuboot专用的映像文件,它是在zImage之前加上一个长度为64字节的“头”,说明这个内核的版本、加载位置、生成时间、大小等信息;其0x40之后与zImage没什么区别。uImage64字节的头结构如下

 */
typedef struct image_header {
	uint32_t ih_magic;	/* Image Header Magic Number	*/
	uint32_t ih_hcrc;	/* Image Header CRC Checksum	*/
	uint32_t ih_time;	/* Image Creation Timestamp	*/
	uint32_t ih_size;	/* Image Data Size		*/
	uint32_t ih_load;	/* Data	 Load  Address	*/
	uint32_t ih_ep;		/* Entry Point Address	used *************	*/
	uint32_t ih_dcrc;	/* Image Data CRC Checksum	*/
	uint8_t	 ih_os;		/* Operating System		*/
	uint8_t	 ih_arch;	/* CPU architecture		*/
	uint8_t	 ih_type;	/* Image Type			*/
	uint8_t	 ih_comp;	/* Compression Type		*/
	uint8_t	 ih_name[IH_NMLEN];	/* Image Name		*/
} image_header_t;

uboot从flash中读出uimage的头部,解析出镜像大小(ih_size),镜像ddr存放地址(ih_load-0x40),内核起始物理地址(ih_ep),uboot同时setup_memory_tags设置bootatag,这里设置的ddr起始地址(0x22500000)和大小(0x03900000)。

起始地址由内核编译生成的zimage头读出(makefile.uboot),大小uboot中指定。

我这边内存分布如下

uboot到kernel启动过程中内存布局变化、初始化

uboot设置pc地址到0x22508000后进入Linux kernel流程,head.S执行内核解压过程,解压地址还是0x22508000,地址重叠由解压的代码来处理。

内核解压后转到start_kernel

start_kernel执行过程中,setup_arch中解析ATAG,对于内存调用parse_tag_mem32,将内存解析出来填入meminfo结构体中。

arm_memblock_init

初始化memblock,将meminfo中记录的内存信息加入到memblock分配器中,同时对_stext--_end这段代码段和数据段内存进行reserve,避免后面进入到伙伴系统中,同时还需要保留的还有页表空间。

head.S中建立了最开始的段页表,每个pgd映射1M空间
#define KERNEL_RAM_VADDR    (PAGE_OFFSET + TEXT_OFFSET)
...
.globl    swapper_pg_dir
.equ    swapper_pg_dir, KERNEL_RAM_VADDR - PG_DIR_SIZE
其中
#define CONFIG_PAGE_OFFSET 0xC0000000
TEXT_OFFSET:0x00008000    (arch/arm/Makefile)
PG_DIR_SIZE 0x4000 (16kb 4096*4byte)

paging_init进行页表映射,包括lowmem,devicemem、iomem、异常向量表等等,内核lowmem优先进行段映射,非1M对其的再进行页映射。

后续memmap_init对系统全局页表管理进行初始化(alloc_node_mem_map),关联每个page和物理页地址。

mem_map以page管理所有物理页,后面给伙伴系统用

随后mm_init中对伙伴系统、kmalloc、vmalloc等

free_all_bootmem_core中对系统中bootmem阶段未申请的内存释放到伙伴系统中。

最后应该类似下面这样:

uboot到kernel启动过程中内存布局变化、初始化