在全志平台里,script.bin用于指定SOC控制器和GPIO等相关的配置. script.bin是由script.fex用工具转换得来.

在uboot启动系统时, uboot的环境变量bootcmd为:

  bootcmd=ext4load mmc 0:1 0x43000000 /script.bin; ext4load mmc 0:1 0x42000000 /uImage; bootm 0x42000000

也就是说script.bin在内核启动前需要放在内存地址0x43000000.
在内核源码”arch/arm/mach-sunxi/sys_config.c”里对script.bin进行处理.


505 int __init script_init(void)
506 {
507     int     i, j, count;
508
509     script_origin_head_t        *script_hdr = __va(SYS_CONFIG_MEMBASE); //SYS_CONFIG_MEMBASE就是内存地址0x43000000
510
511     script_origin_main_key_t    *origin_main;
512     script_origin_sub_key_t     *origin_sub;
513
514     script_main_key_t           *main_key;
515     script_sub_key_t            *sub_key, *tmp_sub, swap_sub;...

script_init函数是在内核启动时,在源码”arch/arm/kernel/setup.c”调用的:

1088 #ifdef CONFIG_ARCH_SUNXI
1089     /* init sys_config script parse */
1090     script_init();
1091 #endif

//
通过阅读sys_config.c里的源码可得知,script.bin其实也是一个文本文件而已,里面的内容是按结构体类型进行存放.

在script.bin文件里:
先存放文件头, 接着存放所有的主键项, 每个主键项的子键又集中存放在一块区域里, 每个子键项的内容又存放在另一个地方.

用到的类型:

#pragma pack(1)typedef struct
{char name[32]; //名字int  offset; //以4字节为单位, 此子键的值与头地址的偏移.如果此键是关于gpio, 子键的值的地址还需减32字节struct {u32 cnt : 16;  // 以4字节为单位,表示子键的值的长度u32 type: 16;  //type of sub key, int(1) / string(2) / gpio(4/5)}pattern;
} script_origin_sub_key_t; //子键的类型typedef struct
{char name[32]; //主键的名字int  sub_cnt; //在此主键下有多少个子键int  offset; // 以4字节为单位,表示此主键的子键开始内容与script.bin的开始地址的偏移
} script_origin_main_key_t; //主键的类型typedef struct
{unsigned int main_cnt; //主键的个数unsigned int length; //值为0, 不明unsigned int version[2]; //版本script_origin_main_key_t    main_key; //第一个主键,主键就是在script.fex里如:[product]
} script_origin_head_t;  //script.bin的文件头 // sprite_gpio0 = port:PL10<1><default><default><default>
typedef struct {char    gpio_name[32]; // 没用int     port; // PLint     port_num; // 10int     mul_sel; // 1int     pull; int     drv_level;int     data;
} script_origin_gpio_t;  //当子键是一个关于IO口的项时,它的值就是这种类型#pragma pack()

/
script.bin里的文件排列:

文件头[主键结构体]
[主键结构体]
[主键结构体]
[主键结构体]
...[子键结构体]
[子键结构体]
[子键结构体]
[子键结构体]
...[子键的值]
[子键的值]
[子键的值]
[子键的值]

在主键结构体里都有offset成员来记录它的第1个子键与文件头的偏移, 在子键结构体由成员offset成员记录它的值与文件头偏移的位置.
文件头里有记录主键的个数,每个主键结构体里由成员sub_cnt记录属于此主键有多少个子键.

获取script.bin里所有主键,子键及其值的测试代码:
app.c

int main(void)
{int fd;script_origin_head_t *head;fd = open("./script.bin", O_RDONLY);if (fd < 0){perror("open script.bin");return 1;}struct stat sbuf;fstat(fd, &sbuf);head = mmap(NULL, sbuf.st_size, PROT_READ, MAP_SHARED, fd, 0);if (MAP_FAILED == head){perror("mmap");return 2;} ////////////////script_origin_main_key_t *main = &head->main_key;script_origin_sub_key_t  *sub;script_origin_gpio_t *gpio;int i, j;for (i = 0; i < head->main_cnt; i++){printf("[%s]:\n", main[i].name);    sub = (char *)head + main[i].offset * 4; //sub指针指向每个主键的第1个子键结构体for (j = 0; j < main[i].sub_cnt; j++){printf("%s = ", sub[j].name);if (sub[j].pattern.type >= 4) //子键是关于gpio的{gpio = (char *)head + sub[j].offset * 4-32;printf("%d, %d, %d, %d, %d\n", gpio->port, gpio->port_num, gpio->mul_sel, gpio->pull, gpio->drv_level);}if (1 == sub[j].pattern.type) //子键的值是intprintf("%d\n", *(int *)((char *)head+sub[j].offset*4));if (2 == sub[j].pattern.type) //子键的值是字符串printf("%s\n", (char *)head+sub[j].offset*4);}printf("\n");}   ///////////////munmap(head, sbuf.st_size);close(fd);return 0;
}

在linux内核源码”sys_config.c”里, 遍历script.bin的内容处理后,用哈希表存放起来.

struct gpio_config {u32 gpio;       /* gpio global index, must be unique */u32     mul_sel;    /* multi sel val: 0 - input, 1 - output... */u32     pull;       /* pull val: 0 - pull up/down disable, 1 - pull up... */u32     drv_level;  /* driver level val: 0 - level 0, 1 - level 1... */u32 data;       /* data val: 0 - low, 1 - high, only vaild when mul_sel is input/output */
};typedef union {int                 val;char                *str;struct gpio_config  gpio;
} script_item_u; //每个子键的值只会是三种类型中的一种. int,  string, gpiotypedef struct {char                        name[SCRIPT_NAME_SIZE_MAX]; //子键名script_item_u               *value;  //子键的值script_item_value_type_e    type;   //子键值的类型int                         hash;  //子键的哈希值void                        *next;
} script_sub_key_t; //用于存放处理过后的子键的项,挂载到主键哈希表的元素里。每个元素就是一个主键.typedef struct {char                name[SCRIPT_NAME_SIZE_MAX];script_sub_key_t    *subkey;script_item_u       *subkey_val;script_item_u       *gpio;int                 gpio_cnt;int                 hash;void                *next;
} script_main_key_t; //用于存放处理过后的主键的哈希表static script_main_key_t   *g_script; //哈希表, 在驱动代码就可以通过哈希表查找相应的主键或子键的值

//
同时, “sys_config.c”里也提供了导出函数,供设备驱动代码里获取script.bin里相应项的配置值.

script_item_value_type_e
script_get_item(char *main_key, char *sub_key, script_item_u *item)
{...
}
EXPORT_SYMBOL(script_get_item);//用法:  script_get_item("target", "boot_clock", &item);int script_get_pio_list(char *main_key, script_item_u **list) //用于获取一个主键下所有关于gpio项的值
{...
}
EXPORT_SYMBOL(script_get_pio_list);//用法: script_get_pio_list("gpio_para", &list);

///

在"sys_config.c"里还提供了用户调用的接口:1)   //读取一个主键下所有子键的接口echo "gpio_para" > /sys/class/script/dumpcat /sys/class/script/dump2)  //指定读取一个主键下的一个子键的值(字符串有乱码)echo "spi_board0 modalias" > /sys/class/script/get_itemcat /sys/class/scripit/get_item

38 全志平台的script.bin在linux内核里的应用分析相关推荐

  1. 香橙派全志H3烧入U-boot和Linux内核以及配置

    全志H3烧入U-boot和Linux内核以及配置 1.U-boot的烧入和U-boot环境配置 1.1U-boot烧入和启动测试 2.编译完的内核处理和烧入 2.1处理内核 2.2烧入内核 U-boo ...

  2. Linux内核抢占实现机制分析【转】

    Linux内核抢占实现机制分析 转自:http://blog.chinaunix.net/uid-24227137-id-3050754.html [摘要]本文详解了Linux内核抢占实现机制.首先介 ...

  3. Linux 内核里的“智能指针”【转】

    转自:http://blog.jobbole.com/88279/ 众所周知,C/C++语言本身并不支持垃圾回收机制,虽然语言本身具有极高的灵活性,但是当遇到大型的项目时,繁琐的内存管理往往让人痛苦异 ...

  4. 【嵌入式Linux学习七步曲之第五篇 Linux内核及驱动编程】Linux内核抢占实现机制分析

    Linux内核抢占实现机制分析 Sailor_forever  sailing_9806@163.com 转载请注明 http://blog.csdn.net/sailor_8318/archive/ ...

  5. linux内核中链表代码分析---list.h头文件分析(一)

    linux内核中链表代码分析---list.h头文件分析(一) 16年2月27日17:13:14 在学习数据结构时,有一个重要的知识点就是链表.对于链表的一些基本操作,它的最好学习资料就是内核中的li ...

  6. Linux内核--网络栈实现分析(二)--数据包的传递过程--转

    转载地址http://blog.csdn.net/yming0221/article/details/7492423 作者:闫明 本文分析基于Linux Kernel 1.2.13 注:标题中的&qu ...

  7. Linux 内核里的“智能指针”

    Linux 内核里的"智能指针" from: http://begeek.cn/post/7889.html?ref=myread 众所周知,C/C++语言本身并不支持垃圾回收机制 ...

  8. linux内核中链表代码分析---list.h头文件分析(二)【转】

    转自:http://blog.chinaunix.net/uid-30254565-id-5637598.html linux内核中链表代码分析---list.h头文件分析(二) 16年2月28日16 ...

  9. OS / linux 内核 read 操作源代码分析

    read 操作是任何操作系统里的基本操作,我们来看一下在 linux 内核里,read 文件是怎样实现的. read 函数在用户空间是由 read 系统调用实现的,由编译器编译成软中断 int 0x8 ...

最新文章

  1. 让VSCode的快捷键切换为WebStorm/IDEA的快捷键、修改颜色主题(深色模式)、文件图标主题
  2. JAVA实现矩形覆盖问题(《剑指offer》)
  3. Hadoop MapReduce容错性分析
  4. document引用图片的src属性能干嘛_如何实现图片懒加载
  5. ITK:计算CovariantVector的范数并将其标准化
  6. Python面向对象,类,继承,多态及鸭子类型,获取类的类型,方法和属性(类似java的反射)
  7. SAP Kyma的Lambda Function describe命令输出
  8. SQL Server有这些属性吗
  9. canvas小程序-快跑程序员
  10. 【工程项目经验】之C语言或汇编语言宏展开
  11. Java多线程之Runable与Thread
  12. 【python基础语法】python实现交换操作a,b = b,a的原理
  13. 保护生态 高山流水 直播伴侣 一对一引流互动脚本 源码
  14. 工资管理系统的开发设计
  15. 中间件的大舞台:高考网上阅卷系统揭秘
  16. LMS自适应波束形成算法(MATLAB)
  17. KeyTool 和 OpenSSL 相互转换 [转]
  18. wps的word文档怎么全选内容_word全选的快捷键 选择Word文档内容小技巧
  19. Ubuntu下的PROXY设置
  20. 浏览器内javascript 转换gbk文本到UTF8编码(chrome, firefox only)

热门文章

  1. Teamviewer被限制,被怀疑商业用途的解决办法。
  2. 中国马铃薯全粉产业经营策略与销售渠道研究报告(2022-2027年)
  3. 微信小程序base64实现小程序码
  4. 其实,我几乎很少看书!
  5. 苹果或3月8日开新品发布会是真的吗?
  6. 使用opencv实现通过摄像头自动输入阿里云身份宝验证码
  7. 如果有一天我老无所依,请把我埋在,新疆的田野上
  8. 按键去抖动c语言编程,单片机实现电脑键盘去抖的编程设计
  9. PHP 测试页index.php phpinfo 空白问题
  10. 电信PPPoE拨号失败,获取不到IP