bootloader对设备树的支持(一)

    xiaoxiao2023-11-14  162

    在之前的文章中介绍过在启动内核时把设备树的地址写到r2寄存器中,并且设备数在内存中的储存信息空间被保留,有无设备树u-boot启动内核的命令是不同的:

    bootm <uImage_addr> // 无设备树 bootm <uImage_addr> <initrd_addr> <dtb_addr> // 有设备树

    例如:

    bootcmd=nand read.jffs2 0x30007FC0 kernel; nand read.jffs2 32000000 device_tree; bootm 0x30007FC0 - 0x32000000 nand read.jffs2 0x30007FC0 kernel; // 读内核uImage到内存0x30007FC0 nand read.jffs2 32000000 device_tree; // 读dtb到内存32000000 bootm 0x30007FC0 - 0x32000000 // 启动, 没有initrd时对应参数写为"-"

    对于uboot怎样把设备树的地址传给linux内核,我会在后面的文章中详细的介绍,在这里我只是简单的介绍,在百度搜索ARM程序调用规则(ATPCS) 写一个c函数 

    c_function(p0, p1, p2) // p0 => r0, p1 => r1, p2 => r2(3个参数分别保存到相应的寄存器)

    定义函数指针 the_kernel, 指向内核的启动地址,然后执行: the_kernel(0, machine_id, 0x32000000);

    armlinux.c中

    /* 100ask for device tree, no initrd image used */ if (argc == 4) { //第三个参数0x32000000就是设备树地址 of_flat_tree = (char *) simple_strtoul(argv[3], NULL, 16); if (be32_to_cpu(*(ulong *)of_flat_tree) == OF_DT_HEADER) { printf ("\nStarting kernel with device tree at 0x%x...\n\n", of_flat_tree); cleanup_before_linux (); //把dtb的地址传到r2寄存器里 theKernel (0, bd->bi_arch_number, of_flat_tree); } else { printf("Bad magic of device tree at 0x%x!\n\n", of_flat_tree); } } 虽然设备树在内存中的空间是被保留的,但是在内存中的存储地址空间不是随便选的,选择设备树在内存中的存储地址需要考虑两个因素: 1、不要破坏u-boot本身; 2、不要挡内核的路: 内核本身的空间不能占用, 内核要用到的内存区域也不能占用 内核启动时一般会在它所处位置的下边放置页表, 这块空间(一般是0x4000即16K字节)不能被占用 

        ARM内存使用框图: 

    ------------------------------ 0x33f80000 ->| u-boot | 分析lds链接文件 ------------------------------ | u-boot所使用的内存(栈等)| ------------------------------ | | | | | 空闲区域 | | | | | | | | | ------------------------------ 0x30008000 ->| zImage | ------------------------------ uImage = 64字节的头部+zImage 0x30007FC0 ->| uImage头部 | ------------------------------ 0x30004000 ->| 内核创建的页表 | head.S ------------------------------ | | | | -----> ------------------------------ | | --- (内存基址 0x30000000) 我如何知道内核放在 0x30008000 在内核目录下执行 mkimage -l arch/arm/boot/uImage 里面显示内核的load address = 0x30008000 最终运行也在0x30008000位置命令示例:

    1.、可以启动:

    nand read.jffs2 30000000 device_tree nand read.jffs2 0x30007FC0 kernel bootm 0x30007FC0 - 30000000

    2、 不可以启动: 内核启动时会使用0x30004000的内存来存放页表,dtb会被破坏

    nand read.jffs2 30004000 device_tree nand read.jffs2 0x30007FC0 kernel bootm 0x30007FC0 - 30004000

     

    最新回复(0)