当前位置: 首页 > news >正文

网站建设工作会议上的讲话做一个网站的费用

网站建设工作会议上的讲话,做一个网站的费用,免费的个人网站html代码,微信公众号开发Linux 设备树详解 Linux 操作系统早期是针对个人电脑设备而开发的操作系统#xff0c;而个人电脑处理器产商较为单一#xff08;例如只有 Intel#xff0c;AMD#xff09;同时个人电脑产商均使用 Intel 或 AMD 制造的处理器#xff0c;业界形成了统一的总线/硬件接口标准…Linux 设备树详解 Linux 操作系统早期是针对个人电脑设备而开发的操作系统而个人电脑处理器产商较为单一例如只有 IntelAMD同时个人电脑产商均使用 Intel 或 AMD 制造的处理器业界形成了统一的总线/硬件接口标准所以 Linux 系统只要遵循这些标准即可。 然而随着 ARM 处理器在嵌入式微型设备上的广泛应用Linux 也支持了 ARM 处理器。但是由于 ARM 架构的授权机制使得任何产商都可以制造 ARM 处理器各产商没有统一标准制造出的 ARM 处理器各不相同。 所以 Linux 系统源码中添加了各产商 ARM 芯片描述代码才能支持各产商的芯片这也导致 Linux 源码包含了大量的 ARM 芯片描述代码。 1. 前言 在 Linux 没有设备树之前 ARM 架构的板级芯片硬件细节通过 C 源码的形式编写在 “arch/arm/plat-xxx” 和 “arch/arm/mach-xxx” 形式命名的文件中不同的硬件对应不同的文件这些不可复用的文件参杂在 Linux 内核源码目录中。 为了从 Linux 内核源码中去除芯片描述代码就引入了设备树设备树的本质是不再使用 C 源码去描述芯片而是使用设备树DTS结构化脚本语法去描述各种芯片。 引入设备树后不同的芯片还是需要对应不同的设备树文件所以设备树文件也很多那引入设备树的意义在哪在于使用一种专属文件去描述可以做到芯片描述与内核源码的分离同时设备树描述的硬件信息更结构化更清晰易懂。 需要知道的是设备树是集成在 OpenFrame 中的开源项目并不是 Linux 的原创现在知道 Linux 设备树中 OF 操作函数命名的由来了吧。 2. 设备树 设备树 Device Tree故名思意就是由各类设备组成的树设备树文件叫做 DTS 即DeviceTree Source。DTS 文件采用树形结构语法描述板级设备信息比如芯片上 CPU 数量DDR 内存基地址SPI/I2C 接口连接的设备。 设备树用于描述硬件设备本质就是用于描述芯片外设的寄存器地址而芯片外设寄存器都是连接在系统总线上的所以设备树树的主干就是系统总线如上图。 3. 设备树工具 现在把芯片的描述内容从 Linux 内核源码中分离出来了并且使用了 .dts 设备树文件格式所以芯片描述部分代码不能再和 Linux 内核源码一起编译了或是说不能再用 GCC 去编译了。此时需要一个专门编译器将设备树文件编译成二进制文件这个编译器叫做 DTC编译后的二进制文件为 .dtb 格式。 总结设备树源码文件 DTS设备树编译器 DTCDTS编译后的二进制文件DTB。 3.1 DTC 编译器 DTC 编译器和 GCC 一样由 C 语言编写而成其源码位于内核的 “scripts/dtc” 目录下该目录下默认是没有 DTC 的可执行文件的而是编译 Linux 时再编译出可执行文件所以在 “scripts/dtc” 目录下除了源码还有一个 Makefile 文件这个用于构建 DTC 源码生成可执行文件。 从 Makefile 文件可以看出 DTC 编译器源码有 dtc.cflattree.cfstree.cutil.c ftdput.c 等文件。 3.2 DTC 使用 如果要使用 DTC 编译 DTS 文件的话只需要进入到 Linux 源码根目录下执行命令 make dtbs 或 make all 即可。执行后 Linux 根目录下的主 Makefile 文件就会调用 “scripts/dtc” 目录下的 DTC 可执行文件去编译设备树目录下指定的 .dts 文件并生成 .dtb 文件。 如果只是编译设备树的话建议使用 make dtbs 命令make dtbs 会编译选中的所有设备树文件。如果只要编译指定的某个设备树比如全志 F1C200S 的那可以执行 make suniv-f1c200s-lctech-pi.dtb 命令。 $ make suniv-f1c200s-lctech-pi.dtb DTC arch/arm/boot/dts/suniv-f1c200s-lctech-pi.dtb3.3 添加 DTS 打开设备树文件所在的 “arch/arm/boot/dts/” 目录打开该目录下的 Makefile 文件可以看到全志 SUNIV 系列芯片相关的设备树文件。 dtb-$(CONFIG_MACH_SUNIV) \suniv-f1c100s-licheepi-nano.dtb \suniv-f1c200s-lctech-pi.dtb \suniv-f1c200s-popstick-v1.1.dtb可知只要配置 CONFIG_MACH_SUNIV 选项为 y 后使用全志 SUNIV 系列芯片的板子对应的 .dts 文件都会被编译为 .dtb 文件。 比如要添加一个新的 SUNIV 系列芯片相关的设备树文件 只需要新建一个对应的 .dts 文件再把对应的 .dtb 文件名添加到 dtb-$(CONFIG_MACH_SUNIV) 分支下即可这样编译设备树的时候就会将对应的 .dts 文件编译为 .dtb 文件。 4. DTS 语法 设备树文件和编程语言一样有一套特定的编写语法规则编写设备树文件就要遵循这套规则不建议自己编写完整的设备树而是复制半导体产商提供的设备树文件再修改定制即可。 4.1 头文件 dtsi 和 C/C 一样DTS 设备树也支持头文件引用设备树头文件后缀名为 .dtsi引用头文件使用 #include 语句。 设备树 .dts 可以引用 .dtsi.dts甚至 C 语言的头文件 .h语法如下所示。 #include suniv.dtsi #include suniv.dts #include suniv.hdtsi 的主要作用 实际应用中 .dtsi 文件用于描述芯片的核心信息比如 CPU 架构主频以及外设信息比如 UARTUSBGPIO寄存器地址范围。芯片产商会把同一个系列芯片共有的外设信息提炼到一个 .dtsi 文件里差异化部分的内容分布到具体芯片的 .dts 文件这样可减少代码的冗余。 例如同一系列的芯片他们的 CPU 架构和 CPU 主频肯定是相同的那这部分信息就可以提炼到一个全系列芯片共有的 .dtsi 文件。 4.2 设备节点 普通的树木由主干枝条和叶子组成而设备树由根节点主干子节点枝条节点属性叶子构成每个节点属性记录着各类设备信息并按所属关系依层次排列就像一棵树木一样。 根节点 设备树根节点名称固定使用 / 表示节点范围用 {} 括号标明属于根节点的属性或子节点就放置在 {} 内部如下所示。 / {............ }每个设备树文件只有一个根节点如果引用了别的包含根节点的设备树文件那这些根节点会合并为一个根节点内容也会叠加合并为一份。 子节点 设备树子节点名称命名规则为 node-nameunit-address子节点范围用 {} 括号标明属于子节点的属性或子节点就放置在 {} 内部如下所示。 / {node-nameunit-address {............}; }其中 node-name 是节点名字为 ASCII 字符串可以任意意命名但是最好能够体现节点的功能比如 serial1c25000 就表示这个节点是串口外设。 而 unit-address 是节点所代表设备的地址或寄存器首地址如果某个节点没有地址或者寄存器的话 unit-address 可忽略比如 cpussoccpu0。 虽然 node-name 代表节点名字但是完整的节点名字为 node-nameunit-address如果要访问节点要使用完整节点名字或标签。 子节点标签 还可以给子节点命名标签规则为 label: node-nameunit-address其中 label 是节点的标签而 : 后面的是节点名字 node-name例如 uart0:serial1c25000 其中 uart0 就是节点标签。 引入 label 的目的是为了方便访问节点有了标签可以通过 label 来访问节点比如通过 uart0 就可以访问 serial1c25000 这个节点而不用输入完整的节点名字。再比如节点 sram:sram10000000节点 label 是 sram而节点名字就很长了为 sram10000000。所以通过 sram 来访问 sram10000000 节点要方便得多。 设备树实例 主要观察实例中根节点以及子节点部分的命名以及规则节点内部涉及到节点的属性相关内容再下一小节讲解。 / {#address-cells 1;#size-cells 1;interrupt-parent intc;clocks {osc24M: clk-24M {#clock-cells 0;compatible fixed-clock;clock-frequency 24000000;clock-output-names osc24M;};};cpus {#address-cells 1;#size-cells 0;cpu0 {compatible arm,arm926ej-s;device_type cpu;reg 0x0;};};soc {compatible simple-bus;#address-cells 1;#size-cells 1;ranges;sram-controller1c00000 {compatible allwinner,suniv-f1c100s-system-control,allwinner,sun4i-a10-system-control;reg 0x01c00000 0x30;#address-cells 1;#size-cells 1;ranges;};} }节点属性 节点属性可以理解为编程语言的变量可以存储数据。赋值采用 keyvalue 对的形式键值对的值可以为空或任意的字节流。 / {node-nameunit-address {keyvalue}; }节点属性支持几种常用的数据类型具体下 (1) 字符串类型例如 compatible “arm,arm926ej-s” 设置 compatible 属性的值为字符串 “arm,arm926ej-s”。 (2) 32 位无符号整数类型例如 reg 0x0 设置 reg 属性的值为整数 0。 (3) 字符串列表类型例如 compatible “licheepi,licheepi-nano”, “allwinner,suniv-f1c100s” 设置属性 compatible 的值为 “licheepi,licheepi-nano” 字符串和 “allwinner,suniv-f1c100s” 字符串。 4.3 标准属性 节点是由属性组成一个节点代表一个设备不同的设备需要的属性不同我们可以自定义属性也可以使用 Linux 支持的标准属性。 compatible 属性 compatible 属性叫 “兼容性” 属性兼容属性对驱动至关重要用于设备匹配驱动程序换句话说是 Linux 内核根据该设备节点的兼容属性为该设备分配一个设备驱动程序。兼容属性值是一个字符串列表字符串列表用于选择设备所要使用的驱动程序具体格式如下。 compatible manufacturer,model;其中 manufacturer 段表示厂商名称而 model 是指硬件模块对应驱动程序的名称例如 compatible “winbond,w25q128” 表示产商是 winbond华邦硬件模块是 w25q128 存储芯片。 我们知道属性支持字符串列表数据类型所以 compatible 可存属性值列表这样设备就有多个兼容属性值设备将多个兼容值逐个的和 Linux 内核驱动程序匹配直到有合适的驱动程序。 实例 驱动程序文件都会有一个 OF 匹配表用来保存一些 compatible 值如果设备节点的 compatible 属性值和 OF 匹配表中的任何一个值相等那么就表示设备可以使用这个驱动那么这个节点就会引用相应的驱动文件。 #ifdef CONFIG_OF static const struct of_device_id i2c_nuvoton_of_match[] {{.compatible nuvoton,npct501},{.compatible winbond,wpct301},{.compatible nuvoton,npct601, .data OF_IS_TPM2},{}, }; MODULE_DEVICE_TABLE(of, i2c_nuvoton_of_match); #endifmodel 属性 model 属性用于描述设备名称这里的设备指的是具体设备产品比如电脑而非芯片外设该属性属于字符串数据类型例如 model “Lichee Pi Nano”。 status 属性 status 属性表示设备状态设备树使用字符串描述设备状态信息所以 status 属性的类型也是字符串可选的状态如下表所示 status 值描述“okay”说明设备是可操作可读可写的。“disabled”说明设备当前不可操作无法读写但是状态可再转变为可操作的比如热插拔设备插入以后详细部分可以查看设备的绑定文档。“fail”说明设备不可操作无法读写设备出现了一系列的错误并且状态无法再转变为可操作的。“fail-sss”和 “fail” 相同sss 部分用于表示检测到的错误内容。 reg 属性 reg 属性的值一般是 addresslength 对该属性一般用于描述设备地址空间资源信息或者设备地址即寄存器信息比如描述 UART 寄存器地址范围信息或者 I2C 器件的设备地址。 其中 address 指的是起始地址length 则指的是地址长度reg 属性可以同时存放多组 addresslength 地址对每个 address length 组合表示一个地址范围具体格式如下。 reg address1 length1 address2 length2 address3 length3 ...;下面 serial 设备节点描述了全志 F1C200S 芯片 UART0 相关信息可以看到 reg 属性中 UART0 的起始地址为 0x01c250地址长度为 0x400。 uart0: serial1c25000 {compatible snps,dw-apb-uart;reg 0x01c25000 0x400;interrupts 1;reg-shift 2;reg-io-width 4;clocks ccu CLK_BUS_UART0;resets ccu RST_BUS_UART0;status disabled; };但是在设置 reg 属性时需要设置几组 address, length 地址对这如何确定这就是下一节涉及的 #address-cells 和 #size-cells 属性的作用。 #address-cells 和 #size-cells 属性 这两个属性一般是配对使用的所以一起讲解这两个属性的类型都是 32 位无符号整形拥有子节点的设备节点用 #address-cells 和 #size-cells 属性设置其子节点的 reg 属性字长。 #address-cells 属性指定 reg 属性的 address 所占用的字长#size-cells 属性指定 reg 属性的 length 所占用的字长。 #address-cells value #size-cells value注意上一节说过 reg 属性可以同时存放多组 addresslength 地址对所以这里的占用字长指的是 reg 属性 address 值或 length 值得个数。 所以 #address-cells 属性指定 reg 属性中 address 的个数#size-cells 属性指定 reg 属性中 length 的个数。 实例 1 soc {......#address-cells 1;#size-cells 1;ranges;uart0: serial1c25000 {compatible snps,dw-apb-uart;reg 0x01c25000 0x400;interrupts 1;reg-shift 2;reg-io-width 4;clocks ccu CLK_BUS_UART0;resets ccu RST_BUS_UART0;status disabled;};...... }实例 2 soc {......#address-cells 1;#size-cells 0;ranges;uart0: serial1c25000 {compatible snps,dw-apb-uart;reg 0x01c25000;interrupts 1;reg-shift 2;reg-io-width 4;clocks ccu CLK_BUS_UART0;resets ccu RST_BUS_UART0;status disabled;};...... }ranges 属性 ranges 是一个地址映射/转换表ranges 属性每个项目由子地址父地址和地址空间长度这三部分组成 rangs child-bus-address parent-bus-address length;(1) child-bus-address子总线地址空间的物理地址由父节点的 #address-cells 属性确定此物理地址所占用的字长。 (2) parent-bus-address父总线地址空间的物理地址同样由父节点的#address-cells 属性确定此物理地址所占用的字长。 (3) length子地址空间的长度由父节点的 #size-cells 属性确定此地址长度所占用的字长。 注意 ranges 属性值可以为空例如 rangs; 这样如果 ranges 属性值为空值说明子地址空间和父地址空间完全相同不需要进行地址转换。 对于一些芯片来说子地址空间和父地址空间完全相同因此会在其设备树中看到不少设备节点得 ranges 属性为空值。 实例 sram-controller1c00000 {......#address-cells 1;#size-cells 1;......sram_d: sram10000 {......ranges 0 0x00010000 0x1000;......}; };name 属性 name 属性用于记录节点名字name 属性值为字符串数据类型。不过 name 属性已经被弃用只能在较老的设备树文件中看见 name 属性所以了解即可。 device_type 属性 该属性用于描述设备的 FCode属性值为字符串数据类型IEEE 1275 会用到此属性。该属性只能用于 cpu 节点或者 memory 节点但是设备树没有 FCode所以该属性也被弃用所以了解即可。 5. 内核兼容检查 普通设备的 compatible 兼容属性用于在 Linux 内核中匹配设备驱动程序而根节点 / 下的 compatible 兼容属性则用于 Linux 内核检查当前设备树对应的设备类型注意这里的设备不是指芯片外设而是完整的硬件产品。 因为设备树是和硬件设备绑定的所以 Linux 内核检查设备树的类型就可以知道当前内核是否支持该硬件设备如果支持则启动 Linux 内核。 以下是全志 F1C200S 芯片的设备树可以看到根节点的兼容属性为 “licheepi,licheepi-nano” 和 “allwinner,suniv-f1c100s”。 / {model Lichee Pi Nano;compatible licheepi,licheepi-nano, allwinner,suniv-f1c100s;aliases {mmc0 mmc0;serial0 uart0;spi0 spi0;};chosen {stdout-path serial0:115200n8;};reg_vcc3v3: vcc3v3 {compatible regulator-fixed;regulator-name vcc3v3;regulator-min-microvolt 3300000;regulator-max-microvolt 3300000;}; };设备检查原理 在 Linux 内核的源码目录 arch/arm/include/asm/mach/ 目录下的 arch.h 文件中定义了 machine_desc 结构体宏定义 DT_MACHINE_START通过该宏定义可以根据芯片架构指定名称定义一个专有名称的 machine_desc 结构体并初始化宏定义如下。 #define DT_MACHINE_START(_name, _namestr) \ static const struct machine_desc __mach_desc_##_name \__used \__section(.arch.info.init) { \.nr ~0, \.name _namestr,#endif宏定义 DT_MACHINE_START 并不完整因为结构体缺少了 } 括号实际上还有配套宏定义 MACHINE_END通过这两个宏定义即可定义完整的结构体。 #define MACHINE_END \ };在 Linux 内核的源码目录 arch/arm/mach-xxx 目录下包含各类芯片的设备描述machine_desc 结构体定义例如全志 F1C200S 芯片对应的 machine_desc 结构体定义如下。 static const char * const suniv_board_dt_compat[] {allwinner,suniv-f1c100s,NULL, };DT_MACHINE_START(SUNIV_DT, Allwinner suniv Family).dt_compat suniv_board_dt_compat, MACHINE_ENDmachine_desc 结构体成员变量 .dt_compat 保存着相应设备的兼容值查看全志 F1C200S 设备树根节点的 compatible 属性值可知与 suniv_board_dt_compat 保存的兼容值相同因此 Linux 内核支持该设备。 6. 节点追加内容 前面说过芯片产商会把同一个系列芯片相同的外设信息提炼到一个 .dtsi 文件中需要这部分信息的 .dts 设备树文件就可以包含这个头文件这样可减少代码的冗余。 所以如果要添加或修改 .dtsi 头文件中的节点内容就不能直接在 .dtsi 文件修改直接修改会影响包含该头文件的其他设备树那该怎么办呢。 通过前面子节点内容知道可以给子节点命名标签label有了节点标签后就可以在 .dts 设备树文件中通过标签访问节点此时即可体现子节点标签的作用通过标签访问节点的规则如下 label {}比如现在要修改设备节点 serial1c25000 的 status 属性那么在 .dts 文件直接通过它的 uart0 标签访问即可如果要访问的节点没有标签先命名标签。 uart0 {pinctrl-names default;pinctrl-0 uart0_pe_pins;status okay; };7. DTS与RootFS Uboot 启动 Linux 内核的同时会将设备树 .dtb 文件传递给 Linux 内核Linux 内核会解析出设备树的节点信息并根据节点名字在根文件系统 /proc/device-tree 目录下创建不同文件夹再将节点内容保存到这些文件夹下。 我们知道设备树属于树状层级结构恰好文件系统目录结构也是如此节点类似文件夹属性类似于文件夹中的文件所以 Linux 内核将解析的设备树节点在根文件系统中表示为 文件夹属性表示为 文件。 例如 clockssoc 属于 / 的子节点所以它们是文件夹的形式compatible#address-cellssize-cells 属于 / 的属性所以它们是文件的形式如下图。 不仅根节点 / 如此所有节点都是这样例如 soc 节点的子节点以文件夹的形式表示属性以文件的形式表示如下图。 8. 特殊节点 8.1 aliases 节点 aliases 节点的主要作用是给节点定义别名定义别名的目的就是为了方便访问节点不过这不常用现在更多是使用节点标签来访问节点。 8.2 chosen 节点 chosen 节点主要作用是用于 Uboot 向 Linux 内核传递数据重点用于 bootargs 参数传递。 Uboot 会在 chosen 节点添加 bootargs 属性并且设置 bootargs 属性值为 bootargs 环境变量的值。 详细查看 https://blog.csdn.net/WANGYONGZIXUE/article/details/115600699
http://www.w-s-a.com/news/895046/

相关文章:

  • 请问有重庆有做网站吗电子政务系统网站建设的基本过程
  • 建设银行管方网站官网最新版cmsv6
  • 网站开发工程师需要会写什么深圳网站(建设信科网络)
  • 台州网站搭建网站建设需求计划
  • 网站app免费下载软件大全大连百度推广哪家好
  • 网站建设的面试要求iis做的网站手机怎么访问
  • 定州市住房保障和城乡建设局网站上海网站建设排行
  • 网站发帖百度收录网站改版后不收录
  • 昆明建设局网站号码网站开发 浏览器兼容性
  • 湖北专业网站建设大全室内设计联盟app下载
  • 网站建设的意义和作用江苏城市建设档案馆网站
  • 华为云速建站贴心的广州网站建设
  • 网页网站开发公司天津seo推广
  • 网站线框图用什么做共享门店新增礼品卡兑换模式
  • 互联网建站是什么seo服务公司上海
  • 象山县城乡建设局网站做网站客户要求分期
  • 什么是网络营销型网站手机网站 图标
  • 全国新农村建设网站外包和劳务派遣哪个好
  • 网站权限控制什么软件做网站描述
  • 建网络商城网站wordpress关于
  • 专业网站建设分类标准重庆网站开发哪家专业
  • 织梦的网站关键词如何自己搭建微信小程序
  • 怎么做基金公司网站韩都衣舍网站建设ppt
  • 外贸网站模板aspnet网站开发 视频
  • 上海植物租赁做网站南浔网站建设
  • 怎么做学校网站做兼职工作上哪个网站招聘
  • 软件下载网站哪个比较好杭州开发小程序
  • 做网站都用什么技术学做名片的网站
  • 备案网站忘记密码乐装网
  • 电商扶贫网站建设淄博网站建设小程序