kernel 动态修改dtb方案

kernel 动态修改dtb方案DTB 是在 uboot 进 kernel 时 被 load 到内存中 然后在 linux 中 start kernel gt setup arch gt unflatten device tree 中 从内存中读取 展开成树型的数据结构 供内核驱动查找 一般来说 linux 中 不会对 dtb 做什么改动 但如果有特殊需求 想统一几个类似产品的不同配置 修改一些驱动参数 而又不想动 uboot 的话 一般 OTA 升级

这里写图片描述
1. 删除property,以删除power-led下yellow下面的default-state为例:

struct device_node *np np = of_find_node_by_name(NULL, "power-led"); np = of_find_node_by_name(np, "yellow"); prop = of_find_property(np, "default-state", NULL); of_remove_property(np, prop);

2. 删除node, 以删除power-led下green这个node为例:

struct device_node *np, *np1, * np2 np = of_find_node_by_name(NULL, "power-led"); np1 = of_find_node_by_name(np, "blue"); np2 = of_find_node_by_name(np, "yellow"); np1->sibling = np2; np1->next = np2; np1->allnext = np2;

3. 添加property, 以添加yellow下enable=true为例:

np = of_find_node_by_name(NULL, "power-led"); np = of_find_node_by_name(np, "yellow"); prop = create_new_property("enable", "true", sizeof("true")); of_add_property(np, prop);

由于用到了early_init_dt_alloc_memory_arch相关的接口,所以贴一下所有这些接口,包含申请device-node和property的封装接口:

static void *unflatten_dt_alloc(void mem, unsigned long size, unsigned long align) { void *res; *mem = PTR_ALIGN(*mem, align); res = (void *)*mem; *mem += size; return res; }
/*we ignore type and data here for basic use.*/ static struct device_node * __init create_new_node(const char* name, unsigned int phandle, const char* full_name, unsigned long _flags) { struct device_node *new_node; void *mem; int malloc_size = 0; char* new_name; char* new_full_name; /*1. calc the whole malloc memory size*/ malloc_size = strlen(name)+1; malloc_size += strlen(full_name)+1; malloc_size += sizeof(struct device_node); /*2 alloc the memory*/ mem = early_init_dt_alloc_memory_arch(malloc_size + 4, 4); memset(mem, 0, malloc_size + 4); new_node = unflatten_dt_alloc(&mem, sizeof(struct device_node), __alignof__(struct device_node)); new_name = unflatten_dt_alloc(&mem, strlen(name)+1, 1); new_full_name = unflatten_dt_alloc(&mem, strlen(full_name)+1, 1); /* 3. fill the data*/ of_node_init(new_node); strcpy(new_name, name); strcpy(new_full_name, full_name); new_node->name = new_name; new_node->full_name = new_full_name; new_node->phandle = phandle; new_node->_flags = _flags; return new_node; }
static struct property * __init create_new_property(char* name, void *value, int value_len) { struct property *new_prop; void *mem; int malloc_size = 0; /* 1. calc the whole malloc memory size */ malloc_size = strlen(name)+1; malloc_size += value_len; malloc_size += sizeof(struct property); /* 2. alloc the memory*/ mem = early_init_dt_alloc_memory_arch(malloc_size + 4, 4); memset(mem, 0, malloc_size + 4); new_prop = unflatten_dt_alloc(&mem, sizeof(struct property), __alignof__(struct property)); new_prop->value = unflatten_dt_alloc(&mem, value_len, 1); new_prop->name = (char*)unflatten_dt_alloc(&mem, strlen(name)+1, 1); /* 3. fill the data*/ memcpy(new_prop->value, value, value_len); new_prop->length = value_len; strcpy(new_prop->name, name); return new_prop; }

4. 添加device_node, 以在key后,添加一个如下wireless-modem的节点为例:

/* add node wireless-modem after key: wireless-modem { compatible = "modem-platdata"; status = "okay"; }; */ np = of_find_node_by_name(NULL, "key"); new_node = create_new_node("wireless-modem", 0, "/wireless-modem", 0); new_node->parent = np->parent; new_node->child = NULL; new_node->sibling = np->sibling; np->sibling = new_node; new_node->next = NULL; new_node->allnext = np->allnext; np->allnext = new_node; /*set compatible = "modem-platdata"*/ np = of_find_node_by_name(NULL, "wireless-modem"); prop = create_new_property("compatible", "modem-platdata", sizeof("modem-platdata")) of_add_property(np, prop); /*set status = "okay"*/ prop = create_new_property("status", "okay", sizeof("okay")); of_add_property(np, prop);

5. 修改property: 以将yellow下default-state=on 改为off为例:

np = of_find_node_by_name(NULL, "power-led"); np = of_find_node_by_name(np, "yellow"); prop = create_new_property("default-state", "off", sizeof("off")); of_update_property(np, new_prop);

6.修改node,参见上面添加,删除node,这里就不再赘述。

另外,需要注意的一点,如果要修改的内容是一个引用结果,比如要将blue中”gpios = <&gpio1 GPIO_A2 GPIO_ACTIVE_HIGH>;“,&gpio1改为&gpio2, 这个就比较麻烦了,因为dts中,这些都是引用,&gpio1其实是一个“linux,phandle”的值,所有被引用的值,如果没有手动设定phandle,那么系统在编译dts->dtb的过程中,会从0,1,2。。。开始自动分配,由于dts引用顺序我们不知道,所以不会知道系统分配个gpio2的是一个什么引用值(虽然这个值在dts确定后,自动生成顺序有管联性,其实是个缺定值),要解决这个问题,那么我们最好事先在gpio1,gpio2。。等可能需要作为被修改值的结构里面,人工指定phandle值,如下,这里指定了phandle,那么,我们在修改或者添加property的时候,就可以直接指定我们手动指定的phandle值了:

gpio2: gpio2@ { compatible = "stm32,gpio-bank"; compatible = "stm32,gpio-bank"; reg = <0x 0x100>; interrupts = 
  
    53 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clk_gates9 
   10>; gpio-controller; interrupt-controller; linux,phandle = < 
   0x00010004>; 
   //手动设定phandle phandle = < 
   0x00010004>; 
   //手动设定phandle }; 
   /* gpios = <&gpio2 GPIO_A2 GPIO_ACTIVE_HIGH>; gpio2 phandle: 0x00010004 */ gpio_data[ 
   0] = be32_to_cpu( 
   0x00010004); 
   //直接设定手动设定的phandle,注意大小端配置 gpio_data[ 
   1] = be32_to_cpu( 
   23); 
   //GPIO_A2 gpio_data[ 
   2] = be32_to_cpu( 
   0); 
   //GPIO_ACTIVE_HIGH prop = create_new_property( 
   "MODEM,reset_gpio", gpio_data, 
   sizeof(gpio_data)); of_add_property(np, prop); 
  
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

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

(0)
上一篇 2026年3月17日 下午12:30
下一篇 2026年3月17日 下午12:30


相关推荐

  • Mobx入门和较佳实践

    Mobx入门和较佳实践

    2021年6月18日
    108
  • python 去除字符串两端的引号[通俗易懂]

    python 去除字符串两端的引号[通俗易懂]使用遥感影像头文件时,需要获得里面的日期和时间信息,得到的字符串两端带有双引号,可以使用eval()函数去除。a='”srting”‘print(a)b=eval(a)print(b)结果:”srting”srting

    2022年6月9日
    131
  • SQL语句存储过程实例详解(面试宝典)「建议收藏」

    SQL语句存储过程实例详解(面试宝典)「建议收藏」本文用3个题目,从建立数据库到创建存储过程,详细讲解数据库的功能。这个问题面试的时候也是经常会用到的,比如写sql语句。题目1学校图书馆借书信息管理系统建立三个表:学生信息表:student字段名称数据类型说明stuIDchar(10)学生编号,主键stuName

    2022年10月5日
    6
  • goland 2021 激活码【中文破解版】

    (goland 2021 激活码)2021最新分享一个能用的的激活码出来,希望能帮到需要激活的朋友。目前这个是能用的,但是用的人多了之后也会失效,会不定时更新的,大家持续关注此网站~https://javaforall.net/100143.htmlIntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,上面是详细链接哦~ML…

    2022年3月21日
    47
  • 异常的中英文对照_圣经中英文对照

    异常的中英文对照_圣经中英文对照在触发异常的地方添加一下代码,就会出现英文的异常Thread.CurrentThread.CurrentCulture=CultureInfo.InvariantCulture;Thread.

    2022年8月3日
    10
  • vue 的双向绑定原理「建议收藏」

    vue 的双向绑定原理「建议收藏」vue采用“数据劫持”和“观察者模式(又叫做发布者-订阅者模式)”相结合的方式,通过Object.defineProperty()来劫持各个属性的setter、getter,在数据变动时发布消息给订阅者,触发相应的监听回调。vue的双向绑定原理,分三步:第一步,“数据劫持”:vue用Object.defineProperty()方法实现数据劫持,为每个属性分配一个订阅者集合的管理数组dep; 第二步,“添加观察者”:在编译的时候在该属性的数组dep中添加订阅者,添加方式包括:v

    2022年8月31日
    5

发表回复

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

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