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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • pycharm安装第三方库失败_pycharm怎么安装python库

    pycharm安装第三方库失败_pycharm怎么安装python库pycharm安装第三方库首先启动pycharm随后通过快捷键进入setting界面,快捷键为ctrl+Als+S点击右上角的加号,添加第三方库在安装之前,首先点击ManageRepositories增加一些国内的镜像源,包括豆瓣http://pypi.douban.com/simple/阿里的,http://mirrors.aliyun.com/pypi/simple/https://pypi…

    2022年8月28日
    7
  • 泰勒公式(泰勒展开式)通俗+本质详解

    泰勒公式(泰勒展开式)通俗+本质详解比较通俗地讲解一下泰勒公式是什么。泰勒公式,也称泰勒展开式。是用一个函数在某点的信息,描述其附近取值的公式。如果函数足够平滑,在已知函数在某一点的各阶导数值的情况下,泰勒公式可以利用这些导数值来做系数,构建一个多项式近似函数,求得在这一点的邻域中的值所以泰勒公式是做什么用的?简单来讲就是用一个多项式函数去逼近一个给定的函数(即尽量使多项式函数图像拟合给定的函数图像),注意,逼近的…

    2022年4月28日
    162
  • kvm网卡模式_java软中断原理

    kvm网卡模式_java软中断原理玩转KVM: 了解网卡软中断RPS

    2022年4月21日
    58
  • codemirror自定义代码提示_96图文编辑器

    codemirror自定义代码提示_96图文编辑器前提写这个的目的是因为之前项目里用到过CodeMirror,觉得作为一款在线代码编辑器还是不错,也看到过有些网站用到过在线代码编辑,当然我不知道他们是用什么做的,这里我把公司项目里用到的那部分抽出来,单独写篇博客,并把抽出来的那部分代码提交到GitHub去简单介绍CodeMirror是一款在线的支持语法高亮的代码编辑器。官网:http://codemirror.net/可…

    2022年8月14日
    5
  • information_schema.schemata_information theory

    information_schema.schemata_information theory1.INFORMATION_SCHEMA简介INFORMATION_SCHEMA提供对数据库元数据的访问,有关MySQL服务器信息,例如数据库或表的名称,列的数据类型或访问权限。INFORMATION_SCHEMA使用说明字符集注意事项INFORMATION_SCHEMA作为SHOW语句的替代INFORMATION_SCHEMA和特权性能注意事项1.1INFOR…

    2025年11月21日
    4
  • javabean总结

    javabean总结

    2021年11月30日
    40

发表回复

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

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