uboot处理dtb「建议收藏」

uboot处理dtb「建议收藏」目录uboot处理dtb传递参数给内核dtb地址选择dtb修改移植fdttitle:uboot处理dtbdate:2019/4/2817:18:19toc:true—uboot处理dtb传递参数给…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全家桶1年46,售后保障稳定


title: uboot处理dtb
date: 2019/4/28 17:18:19
toc: true

uboot处理dtb

传递参数给内核

之前在分析内核启动参数的时候,可以看到内核处理的dtb的地址是原来atag的地址也就是R2,所以就是在转入kernel参数为的第3个为dtb地址即可

我们的uboot是这么启动的

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

Jetbrains全家桶1年46,售后保障稳定

所以就是讲第4个参数读取并转换即可

/* 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);
    }

}

最终的启动流程如下

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

dtb 地址选择

使用mkimage -l arch/arm/boot/uImage来查看内核的加载地址,然后放置到正确的位置

  • 不要破坏u-boot本身
  • 内核本身的空间不能占用, 内核要用到的内存区域也不能占用
  • 内核启动时一般会在它所处位置的下边放置页表, 这块空间(一般是0x4000即16K字节)不能被占用
                    ------------------------------
 0x33f80000       ->|    u-boot                  | 分析lds链接文件
                    ------------------------------
                    |    u-boot所使用的内存(栈等)|
                    ------------------------------
                    |                            |
                    |                            |
                    |        空闲区域            |
                    |                            |
                    |                            |
                    |                            |
                    |                            |
                    ------------------------------
 0x30008000       ->|      zImage                |
                    ------------------------------  uImage = 64字节的头部+zImage
 0x30007FC0       ->|      uImage头部            |
                    ------------------------------
 0x30004000       ->|      内核创建的页表        |  head.S
                    ------------------------------
                    |                            |
                    |                            |
             -----> ------------------------------
             |
             |
             --- (内存基址 0x30000000)

正确操作

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

破坏页表不能启动哦

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

dtb修改

dtb的二进制文件还算简单,可以直接来修改即可,具体的修改就是要注意一些字节长度和偏移

具体的步骤简述一下,我觉得没必要搞,还是dts文件方便

例子1. 修改属性的值,
假设 老值: len
     新值: newlen (假设newlen > len)

a. 把原属性val所占空间从len字节扩展为newlen字节:
   把老值之后的所有内容向后移动(newlen - len)字节
b. 把新值写入val所占的newlen字节空间
c. 修改dtb头部信息中structure block的长度: size_dt_struct
d. 修改dtb头部信息中string block的偏移值: off_dt_strings
e. 修改dtb头部信息中的总长度: totalsize



例子2. 添加一个全新的属性
a. 如果在string block中没有这个属性的名字,
   就在string block尾部添加一个新字符串: 属性的名
   并且修改dtb头部信息中string block的长度: size_dt_strings
   修改dtb头部信息中的总长度: totalsize
b. 找到属性所在节点, 在节点尾部扩展一块空间, 内容及长度为: 
   TAG      // 4字节, 对应0x00000003
   len      // 4字节, 表示属性的val的长度
   nameoff  // 4字节, 表示属性名的offset
   val      // len字节, 用来存放val
c. 修改dtb头部信息中structure block的长度: size_dt_struct
d. 修改dtb头部信息中string block的偏移值: off_dt_strings
e. 修改dtb头部信息中的总长度: totalsize

移植fdt

uboot也有现成的源代码,需要移植,具体错误可以参考

cmd/fdt.c
在编译文件时可以用"-I"选项指定头文件目录
比如: arm-linux-gcc -I <dir> -c -o ....,对于u-boot来说, 一般就是源码的include目录。

常用命令如下

nand read.jffs2 32000000 device_tree  // 从flash读出dtb文件到内存(0x32000000)
fdt addr 32000000                     // 告诉fdt, dtb文件在哪
fdt print /led pin                    // 打印/led节点的pin属性
fdt get value XXX /led pin            // 读取/led节点的pin属性, 并且赋给环境变量XXX
print XXX                             // 打印环境变量XXX的值
fdt set /led pin <0x00050005>         // 设置/led节点的pin属性
fdt print /led pin                    // 打印/led节点的pin属性
nand erase device_tree                // 擦除flash分区
nand write.jffs2 32000000 device_tree // 把修改后的dtb文件写入flash分区

转载于:https://www.cnblogs.com/zongzi10010/p/10793084.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/207151.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 多态性_dna多态性的四个类型

    多态性_dna多态性的四个类型多态性的重要性:多态性是面向对象程序设计的一个强大机制:为名称相同的方法提供不同的实现方式,继承自同一基类的不同派生类可以为同名方法定义不同的功能,统一方法作用于不同类的对象,可以有不同的解释,产生

    2022年8月4日
    12
  • 系统临时文件的写和读:createTempFile和tempFileContent[通俗易懂]

    写java的时候,有时候查到的数据暂时用不到,我们可以把它写到一个临时文件中。今天写项目的时候发现了这个好方法。将context的内容写到临时文件@PostMapping("/temp")@ResponseBodyStringtemp(@RequestParamStringcontent)throwsIOException{FiletempFil…

    2022年4月11日
    49
  • 我在武汉新东方上过的8个老师是谁_武汉新东方学校靠谱吗

    我在武汉新东方上过的8个老师是谁_武汉新东方学校靠谱吗上新东方的总结、感想。对新东方还是有一点留恋的。。。

    2025年11月10日
    6
  • 【计算机网络(微课版)】第3章 数据链路层 课后习题及答案

    【计算机网络(微课版)】第3章 数据链路层 课后习题及答案3-1数据链路(即逻辑链路)与链路(即物理链路)有何区别?“电路接通了”与“数据链路接通了”的区别何在?(1)数据链路与链路的区别在于——数据链路除链路外,还必须有一些必要的规程来控制数据的传输。因此,数据链路比链路多了实现通信规程所需要的硬件和软件。(2)“电路接通了”表示链路两端的结点交换机已经开机,物理连接已经能够传送比特流了。但是,数据传输并不可靠。在物理连接…

    2022年7月21日
    19
  • spssχ2检验_spss交叉表分析方法与步骤 + SPSS卡方检验结果的阅读

    spssχ2检验_spss交叉表分析方法与步骤 + SPSS卡方检验结果的阅读spss中交叉分析主要用来检验两个变量之间是否存在关系,或者说是否独立,其零假设为两个变量之间没有关系。在实际工作中,经常用交叉表来分析比例是否相等。例如分析不同的性别对不同的报纸的选择有什么不同。spss交叉表分析方法与步骤:1、在spss中打开数据,然后依次打开:analyze–descriptive–crosstabs,打开交叉表对话框2、将性别放到行列表,将对读物的选择变量放到列,这样…

    2022年5月17日
    54
  • rhel7+apache+c cgi+动态域名实现web访问

    1.申请动态域名/安装no-ip客户端https://blog.csdn.net/lee244868149/article/details/440958352.yum安装httpd两种方法安

    2021年12月29日
    35

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号