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


相关推荐

  • 类 InputStreamReader[通俗易懂]

    类 InputStreamReader[通俗易懂]InputStreamReader 是字节流通向字符流的桥梁:它使用指定的 charset 读取字节并将其解码为字符。它使用的字符集可以由名称指定或显式给定,或者可以接受平台默认的字符集。每次调用 InputStreamReader 中的一个 read() 方法都会导致从底层输入流读取一个或多个字节。要启用从字节到字符的有效转换,可以提前从底层流读取更多的字节,使其超过满足当前读取操作所需的字节。

    2022年9月26日
    3
  • Redis的数据过期清除策略 与 内存淘汰策略

    Redis的数据过期清除策略 与 内存淘汰策略

    2021年4月10日
    136
  • HOJ 2245 浮游三角胞(数学啊 )

    HOJ 2245 浮游三角胞(数学啊 )

    2022年1月23日
    48
  • 电平转换芯片整理「建议收藏」

    电平转换芯片整理「建议收藏」最近做项目遇到的电平转换芯片比较多,这两天会持续汇总整理一下。1.何为电平转换芯片?简言之,就是在不同电压等级的系统电路中,两者通讯也满足信号电平匹配,如果不匹配,就必须要电平转换,电平转换芯片就是为这个而存在的。2.那电平转换都有哪些类型?这个要从不同通信协议的信号电平说起,我们通常在电子电路中,遇到的都是24V以下的电路系统,举个典型的例子–单片机系统,在单片机电路中,常见的信号电平以3.3V和5V为主,比如C51内核的(ATMEL,此处说明一点:ATMEL公司是搞芯片的,51架构是intel搞

    2022年8月10日
    5
  • 图解Kafka的服务端的网络通信模型

    图解Kafka的服务端的网络通信模型在开始讲解Kafka的网络通信模型之前,我们有必要先简单了解一下:线程模型Reactor模式Reactor模式Reactor模式,是指通过一个或多个输入同时传递给服务处理器的服务请求的事件驱动处理模式。服务端程序处理传入多路请求,并将它们同步分派给请求对应的处理线程,Reactor模式也叫Dispatcher模式。即I/O多了复用统一监听事件,收到事件后分发(Dispatch给某进程),是编写高性能网络服务器的必备技术之一。根据Reactor的数量和处理资源池线程的数量不同,有

    2022年7月14日
    17
  • ipconfig 和ip addr的区别「建议收藏」

    ipconfig 和ip addr的区别「建议收藏」今天在玩DNS解析记录的追踪。nslookup查了一下我们业务域名对应的ip。得到一个完全不知道的ip。此时我登录到应用服务器上,使用ipa查看了该服务器的网络配置。并没有这个ip。百思不得其解。搞了一天终于明白了,一共两个问题:1、ipaddr和ifconfig显示的不一样?使用ifconfig发现了使用nslookup查到的ip,而ipaddr竟然不显示那个ip地址。原因如下:net-tools起源于BSD,自2001年起,Linux社区已经对其停止维护..

    2022年7月27日
    19

发表回复

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

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