• 翻译:A Tutorial on the Device Tree (Zynq) -- Part II


    A Tutorial on the Device Tree (Zynq) -- Part II

    设备树结构

    Zynq的设备树如下:

    /dts-v1/;
    / {
      #address-cells = <1>;
      #size-cells = <1>;
      compatible = "xlnx,zynq-zed";
      interrupt-parent = <&gic>;
      model = "Xillinux for Zedboard";
      aliases {
        serial0 = &ps7_uart_1;
      } ;
      chosen {
        bootargs = "consoleblank=0 root=/dev/mmcblk0p2 rw rootwait earlyprintk";
        linux,stdout-path = "/axi@0/uart@E0001000";
      };
    
      cpus {
    
          [ ... CPU definitions ... ]
    
       } ;
      ps7_ddr_0: memory@0 {
        device_type = "memory";
        reg = < 0x0 0x20000000 >;
      } ;
      ps7_axi_interconnect_0: axi@0 {
        #address-cells = <1>;
        #size-cells = <1>;
        compatible = "xlnx,ps7-axi-interconnect-1.00.a", "simple-bus";
        ranges ;
    
          [ ... Peripheral definitions ... ]
    
      } ;
    } ;
    

    这是Xillinux使用的设备树,删去了两个部分:一个描述CPUs(比较无趣),另一个定义外设(太长了,后面再深入其中的信息)。

    默认使用的dts是/boot/devicetree-3.3.0-xillinux-1.0.dts

    在第一行版本描述之后,设备树以一个斜杠/开始,表示这是树的根, 然后是大括号。从DTS编译器的角度来看,大括号包含大更深的层级(相当于文件系统里的目录结构)。内核代码会遍历这颗树,在某个路径上抓取到想要的信息(就像在文件系统的某个路径上读文件)。

    树的结构是以内核期望为准。其中的赋值对dtc来说没有意义。事实上,树中的许多赋值语句都会被内核忽略掉,就像某个文件存在于文件系统中,但没有程序去打开它。

    从用户空间访问数据

    与文件系统作类比并不是想当然,内核真的实现了这个文件系统/proc/device-tree:每个大括号表示一个目录,目录名是大括号前面的字符串。

    如:

    # hexdump -C '/proc/device-tree/#size-cells'
    00000000  00 00 00 01                                       |....|
    00000004
    # hexdump -C '/proc/device-tree/axi@0/compatible'
    00000000  78 6c 6e 78 2c 70 73 37  2d 61 78 69 2d 69 6e 74  |xlnx,ps7-axi-int|
    00000010  65 72 63 6f 6e 6e 65 63  74 2d 31 2e 30 30 2e 61  |erconnect-1.00.a|
    00000020  00 73 69 6d 70 6c 65 2d  62 75 73 00              |.simple-bus.|
    0000002c
    

    或直接:

    # cat '/proc/device-tree/axi@0/compatible'
    xlnx,ps7-axi-interconnect-1.00.asimple-bus
    

    注意dts文件中axi@0的定义:

    ps7_axi_interconnect_0: axi@0
    冒号之前的是标签,只出现在DTS文件中,而不会出现在DTB文件里。而靠近大括号的字符串为目录名。

    如上示范,赋值操作在/proc里表示为一个文件,文件名为等号左边的字符串,文件内容为等号右边的字符串。如果只没有等号, 则创建一个空文件。

    上例显示,设备树即能方便地向用户空间程序传递信息,也能向内核传递信息, /proc/device-tree虚拟文件系统让这些信息变得可访问。毋须多言,内核中有一套API可访问设备树结构和数据。

    你可能注意到了整型以大端形式表示,Zynq处理器是小端的,留意这点。

    设备树里的启动参数

    一般有三个地方可以放置内核启动命令:

    • 内核配置的CONFIG_CMDLINE参数
    • 由bootloader传递给内核
    • 在设备树的chosen/bootargs下描述

    使用哪一个取决于内核的配置。在Xillinux中,使用设备树chosen/bootargs里描述的cmdline。

    选择哪个UART来输出内核启动信息是在初始代码里写死的。这里即使删掉ps7_uart_1: serial@e0001000这一行,启动信息仍会从UART中输出,只是不会再出现/dev/ttyPS0设备节点了。

    "alias"和"linux,stdout-path"赋值语句是这个架构历史遗留的,在这里没有意义。

  • 相关阅读:
    Nuget常用命令(转)
    Core使用SAP Web Service
    jquery.dataTables动态列--转
    jqGrid随窗口大小变化自适应大小-转
    30个值得推荐的数据可视化工具--转
    Automapper问题记录
    MVC及MVC Core在filter中如何获取控制器名称和Action名称
    .Net Core使用 MiniProfiler 进行性能分析(转)
    Core中使用Hangfire
    ASP.NET 多环境下配置文件web.config的灵活配置---转
  • 原文地址:https://www.cnblogs.com/sammei/p/3978442.html
Copyright © 2020-2023  润新知