全面解析PowerPC架构下的扁平设备树FDT

4.2uboot对设备树的支持——dtb的修改原理 本节说明。在uboot中,有一些命令支持。当我们想要修改dtb文件时,可以直接,然后生成,再将。或者,我们也可以在中使用,直接修改dtb文件。修改完成后,再将新的dtb文件保存在板子上,以后启动时就可以使用这个新的dtb文件了。实际上,就是fdt命令在最新的uboot版本中已经有支持了,但是还不支持,所以需要修改uboot代码,增加支持fdt指令(从新版本中移植)。在移植之前,先了解一下在fdt指令修改dtb的原理。 阅读详情

全面解析PowerPC架构下的扁平设备树FDT


Sailor_forever  sailing_9806#163.com

(本原创文章发表于Sailor_forever 的个人blog,未经本人许可,不得用于商业用途。任何个人、媒体、其他网站不得私自抄袭;网络媒体转载请注明出处,增加原文链接,否则属于侵权行为。如有任何问题,请留言或者发邮件给sailing_9806@163.com)
http://blog.youkuaiyun.com/sailor_8318/archive/2009/12/26/5078959.aspx



【摘要】本文以MPC8378处理器、Linux2.6.25内核及U-boot1.3.4为例,讲述了如何在PowerPC架构下使用FDT。首先介绍了引入FDT的背景,接着详细介绍了FDT的组成及制作。最后介绍了U-boot及内核如何支持FDT。


【关键字】PowerPC,MPC8378,DTS,DTB,FDT,device node,property,compatible


1    背景    2
2    设备树的描述方式    2
2.1    root Node    3
2.2    chosen    3
2.3    cpus Node    3
2.4    System Memory    5
2.5    Devices    5
2.5.1    Compatible属性    6
2.5.2    Addressing    6
2.6    Interrupts and Interrupt Controllers    7
3    如何制作设备树映像    8
3.1    输入    8
3.2    输出    9
3.3    命令格式    9
4    设备树的传递途径    9
4.1    U-boot对FDT的支持    10
4.2    如何配置FDT    10
4.3    如何传递设备树    10
5    内核如何解析设备树    12
6    设备树对驱动设计产生的影响    15



1    背景
通常情况下,桌面机和服务器可以兼容大部分软件。最好的结果就是当添加新硬件时,无需重新编译Linux内核。标准的固件接口可以保证bootloader将正确的参数传递给内核。PC可以采用bios,PowerPC and Sparc采用Open-Firmware接口。但是对于嵌入式系统,软件差别太大,内核本身也是定制的,bootloader只需要传递很少的参数,因为大部分信息都是硬编码在系统的配置中的。这样同一个内核映像很难同时使用在多个不同的平台上。

早期的PowerPC平台采用特定的数据结构bd_info来传递参数,其定义在include/asm-ppc/ppcboot.h,#define来定义特定平台的数据域,但并没有什么信息来说明当前采用的是那个bd_info结构,所以必须保证在内核和bootloader中同时更新,以便保持一致。

合并32-bit (arch/ppc) 和 64-bit (arch/ppc64) PowerPC的同时,决定重新整理固件接口,建立新的目录arch/powerpc,这里所有的平台必须向内核提供Open Firmware风格的设备树,以便内核启动时可以获得当前平台的硬件配置。

2    设备树的描述方式
简单的说设备书是一种描述硬件配置信息的数据结构,包括CPU,内存,总线及相关外设。内核启动时可以解析这些信息,以此决定如何配置内核及加载那些驱动。该数据结构有一个单一的根节点“/”。每个节点有个名字并可以包含多个子节点。数据的格式遵循IEEE standard 1275。

Device tree source (.dts)采用一种易编辑的文本方式来表达设备树,device tree compiler tool (dtc)将.dts转换成binary device tree blob(.dtb)。设备树并不是控制系统设备的唯一方法,比如内核对USB和PCI已经有非常方便的检测机制。

/ { // the root node
    an-empty-property;
   
    a-child-node {
    array-prop = <0x100 32>;
    string-prop = "hello, world";
    };
   
    another-child-node {
    binary-prop = [0102CAFE];
    string-list = "yes","no","maybe";
    };
};
Figure 1: Simple example of the .dts file format

2.1    root Node
设备树的起点是根节点,Model和compatible属性指明了当前平台的名字,格式为<mfg>,<board>:
Mfg是vendor,board是板子模型

Compatible属性不一定非得要,但是当两个系统在硬件配置上基本一致时,这个参数可以用于辨别当前系统。
/ {
    model = "fsl,mpc8377rdb";
    compatible = "fsl,mpc8377rdb";
    #address-cells = <1>;
    #size-cells = <1>;

    aliases {
        ethernet0 = &enet0;
        ethernet1 = &enet1;
        serial0 = &serial0;
        serial1 = &serial1;
        //pci0 = &pci0;
    };
    // Child nodes go here
};
Figure 3: Example system root node

2.2    chosen
此节点并不真正代表设备节点,而是一些虚拟的由bootloader传递给内核的一些参数,包括bootargs(cmdline)和initrd等。一般由bootloader在启动内核时添加此节点。

2.3    cpus Node
cpus节点是root节点的子节点,对于多核CPU系统,每个CPU有一个子节点。Cpus节点并不需要特别的特性,但是通常习惯指定#address-cells = <1>和#size-cells = <0>,这指定了各个CPU节点的reg属性的格式,其用于编码物理CPU号。

CPU节点的格式为cpu@x,model属性描述CPU类型,其他的是时钟频率及cache 相关属性。
cpus {
    #cpus = <1>;
    #address-cells = <1>;
    #size-cells = <0>;

    PowerPC,8377@0 {
        device_type = "cpu";
        model = "PowerPC, 8377";
        reg = <0x0>;
        d-cache-line-size = <32>;
        i-cache-line-size = <32>;
        d-cache-size = <32768>;
        i-cache-size = <32768>;
        timebase-frequency = <0>;
        bus-frequency = <0>;
        clock-frequency = <0>;
    };
};
Figure 4: cpus node

cpus {
    #cpus = <2>;
    #address-cells = <1>;
    #size-cells = <0>;

    PowerPC,8641@0 {
        device_type = "cpu";
        reg = <0>;
        d-cache-line-size = <20>;    // 32 bytes
        i-cache-line-size = <20>;    // 32 bytes
        d-cache-size = <8000>;        // L1, 32K
        i-cache-size = <8000>;        // L1, 32K
        timebase-frequency = <0>;    // 33 MHz, from uboot
        bus-frequency = <0>;        // From uboot
        clock-frequency = <0>;        // From uboot
        32-bit;
        linux,boot-cpu;
    };
    PowerPC,8641@1 {
        device_type = "cpu";
        reg = <1>;
        d-cache-line-size = <20>;    // 32 bytes
        i-cache-line-size = <20>;    // 32 bytes
        d-cache-size = <8000>;        // L1, 32K
        i-cache-size = <8000>;        // L1, 32K
        timebase-frequency = <0>;    // 33 MHz, from uboot
        bus-frequency = <0>;        // From uboot
        clock-frequency = <0>;        // From uboot
        32-bit;
    };
};
2.4    System Memory
描述系统内存的节点成为memory node,其为root节点的子节点,通常只用一个memory节点描述系统所有的内存范围,reg属性用来定义当前可用的各个memory范围。
memory {
    device_type = "memory";
    reg = <0x00000000 0x40000000>;    // 256MB at 0
};
Figure 5: Memory node

2.5    Devices
一系列节点用于描述系统总线及设备,每个总线及设备在设备树种都有自己的节点。处理器的local bus通常直接作为根节点的子节点,附着在local bus上的Devices and bridges将作为其子节点。
下图显示的PLB bus上的设备包括interrupt controller, an Ethernet device,
及 OPB bridge,OPB总线上有serial devices and a Flash device
plb {
    compatible = "simple-bus";
    #address-cells = <1>;
    #size-cells = <1>;
    ranges;
    UIC0: interrupt-controller {
    compatible = "ibm,uic-440gp",
    "ibm,uic";
    interrupt-controller;
    #interrupt-cells = <2>;
    };
    ethernet@20000 {
    compatible = "ibm,emac-440gp";
    reg = <0x20000 0x70>;
    interrupt-parent = <&UIC0>;
    interrupts = <0 4>;
    };
    opb {
        compatible = "simple-bus";
        #address-cells = <1>;
        #size-cells = <1>;
        ranges = <0x0 0xe0000000
        0x20000000>;
        serial@0 {
        compatible = "ns16550";
        reg = <0x0 0x10>;
        interrupt-parent = <&UIC0>;
        interrupts = <1 4>;
        };
        serial@10000 {
        compatible = "ns16550";
        reg = <0x10000 0x10>;
        interrupt-parent = <&UIC0>;
        interrupts = <2 4>;
        };
        flash@1ff00000 {
        compatible = "amd,s29gl256n",
        "cfi-flash";
        reg = <0x1ff00000 0x100000>;
        };
    };
};
Figure 6: Simple System Device Hierarchy

2.5.1    Compatible属性
几乎每个设备都有compatible属性,OS利用此关键字来确定node所描述的设备,通常compatible字符串的格式如下:
<manufacturer>,<part-num>
对于每个特定的compatible值,需要为该设备定义一个device tree binding。
有时候compatible是一系列字符串,如果某个设备在寄存器级别和某个旧设备兼容,则可以同时指定多个字串,这样OS就知道这两个驱动是兼容的。通常该设备的compatible字串在前,然后是兼容的旧设备的字串。

2.5.2    Addressing
设备地址由reg属性指定,其为一系列cell单元。格式如下:
reg = <base1 size1 [base2 size2 [...]]>;
每个reg的实际大小有父节点的#address-cells and #size-cells属性决定,#address-cells是用来指定base address基地址的cells个数,#size-cells是用来指定region size的cells个数。Reg所使用的cells个数必须是(#address-cells + #size-cells)的倍数。

Reg定义的是bus address,而非system address,bus address是设备依赖的总线上的相对地址,或者更专业的说bus address是相对于父节点的。

Ranges属性可以将bus address映射到父节点一级,格式如下:
ranges = <addr1 parent1 size1 [...]>;
addr为总线地址,宽度为#address-cells,parent是父节点总线上的地址,宽度为父节点的#address-cells,size宽度为父节点的#size-cells。但是当总线地址和父节点地址映射关系为1:1时,可以简化映射关系:
ranges;

在本示例中,Flash在OPB总线上的地址为0x1ff00000,但OPB总线中,PLB bus address 0xe0000000 映射到了0x0000000 on the OPB bus,因此Flash设备的地址为0xfff00000。

2.6    Interrupts and Interrupt Controllers
设备树的自然布局很方便描述设备间的简单关系,但是中断系统是个比较复杂的例子。可以将serial device描述为OPB总线的子节点,但也可以说其是interrupt controller设备的子节点,那么如何描述呢?目前的规范是,自然树的结构适用于描述那些寻址和控制设备的主要接口,次要连接可以通过phandle属性来描述相互之间的关系,其为节点中的一个指针,指向另一个节点。

对于中断连接,设备节点利用interrupt-parent and interrupts属性来描述到interrupt controller的连接。interrupt-parent是指向描述interrupt controller节点的指针,interrupts是interrupt controller可以触发的一系列中断信号。

Interrupt controller节点必须定义空属性interrupt-controller,同时定义#interrupt-cells,确定几个cells描述一个中断信号。由于Interrupt controller节点在设备树种被其他节点链接,因此必须定义属性linux,phandle = <xx>。

对于大部分SOC系统,通常只有一个interrupt controller,,但是多个interrupt controller之间可以级联。interrupt controller和设备之间的关系就形成了interrupt tree。

对于serial device node,interrupt-parent属性定义了其在中断树中与其父节点的关系。Interrupts属性定义了特定的中断标识,其格式取决于中断树中父节点的#interrupt-cells,通常#interrupt-cells为2,这样第一个值表示interrupt controller中的硬件中断编号,第二个值表示中断触发方式:电平触发或者边沿触发。

/* IPIC
 * interrupts cell = <intr #, sense>
 * sense values match linux IORESOURCE_IRQ_* defines:
 * sense == 8: Level, low assertion
 * sense == 2: Edge, high-to-low change
 */
pic@700 {
    linux,phandle = <700>;
    interrupt-controller;
    #address-cells = <0>;
    #interrupt-cells = <2>;
    reg = <700 100>;
    built-in;
    device_type = "ipic";
};

serial@4500 {
    device_type = "serial";
    compatible = "ns16550";
    reg = <4500 100>;
    clock-frequency = <0>;
    interrupts = <9 8>;
    interrupt-parent = <700>;
};

3    如何制作设备树映像
Device tree compiler(dtc)负责将文本格式的设备树转换成OS可以识别的格式。
3.1    输入
Dtc接受三种输入格式:
源文件,即device tree source;
Blob (dtb),flattened tree format,主要用于检查现有的DTB映像;
FS文件系统,/proc/device-tree下面的文件树目录,主要用于从当前运行的内核中获得设备树映像。

-sh-3.1# ls -al /proc/device-tree
ls -l /proc/device-tree/
-r--r--r--    1 root     root            4 Jan  1 00:05 #address-cells
-r--r--r--    1 root     root            4 Jan  1 00:05 #size-cells
dr-xr-xr-x    2 root     root            0 Jan  1 00:05 aliases
dr-xr-xr-x    2 root     root            0 Jan  1 00:05 chosen
-r--r--r--    1 root     root           15 Jan  1 00:05 compatible
dr-xr-xr-x    3 root     root            0 Jan  1 00:05 cpus
dr-xr-xr-x   15 root     root            0 Jan  1 00:05 immr@e0000000
dr-xr-xr-x    4 root     root            0 Jan  1 00:05 localbus@e0005000
dr-xr-xr-x    2 root     root            0 Jan  1 00:05 memory
-r--r--r--    1 root     root            1 Jan  1 00:05 name
dr-xr-xr-x    2 root     root            0 Jan  1 00:05 pci@e000a000
dr-xr-xr-x    2 root     root            0 Jan  1 00:05 redbox-fpga-card0@F0000000
dr-xr-xr-x    2 root     root            0 Jan  1 00:05 redbox-fpga-card1@F0000000
dr-xr-xr-x    2 root     root            0 Jan  1 00:05 redbox-fpga-dbstate@F0000000
dr-xr-xr-x    2 root     root            0 Jan  1 00:05 redbox-fpga-misc@F0000000

ls -l /proc/device-tree/immr/@e0000000/
-r--r--r--    1 root     root            4 Jan  1 00:06 #address-cells
-r--r--r--    1 root     root            4 Jan  1 00:06 #size-cells
-r--r--r--    1 root     root            4 Jan  1 00:06 bus-frequency
-r--r--r--    1 root     root           11 Jan  1 00:06 compatible
-r--r--r--    1 root     root            4 Jan  1 00:06 device_type
dr-xr-xr-x    2 root     root            0 Jan  1 00:06 ethernet@24000
dr-xr-xr-x    2 root     root            0 Jan  1 00:06 ethernet@25000
dr-xr-xr-x    2 root     root            0 Jan  1 00:06 i2c@3000
dr-xr-xr-x    3 root     root            0 Jan  1 00:06 i2c@3100
dr-xr-xr-x    2 root     root            0 Jan  1 00:06 interrupt-controller@700
dr-xr-xr-x    3 root     root            0 Jan  1 00:06 mdio@24520
-r--r--r--    1 root     root            5 Jan  1 00:06 name
dr-xr-xr-x    2 root     root            0 Jan  1 00:06 power@b00
-r--r--r--    1 root     root           12 Jan  1 00:06 ranges
-r--r--r--    1 root     root            8 Jan  1 00:06 reg
dr-xr-xr-x    2 root     root            0 Jan  1 00:06 serial@4500
dr-xr-xr-x    2 root     root            0 Jan  1 00:06 serial@4600
dr-xr-xr-x    2 root     root            0 Jan  1 00:06 spi@7000
dr-xr-xr-x    2 root     root            0 Jan  1 00:06 timer@500
dr-xr-xr-x    2 root     root            0 Jan  1 00:06 usb@23000
dr-xr-xr-x    2 root     root            0 Jan  1 00:06 wdt@200

3.2    输出
Blob (dtb),主要用于从DTS获得设备树映像;
source (dts), 当输入参数为Blob (dtb),可以“反汇编”出设备树源文件;
assembler source (asm),其最终可以编译成.O文件,可以链接到bootloader中或者frrmware image。

3.3    命令格式
dtc [-I <input -format > ] [-O <output -format > ] [-o output-filename] [-V output_version] input_filename

dtc -I dts -O dtb -S 0x3000 -o obj_name.dtb source_name.dts
-S 指定的是生成的dtb文件的大小,需要适当地扩大以供u-boot 创建/choose节点时使用

4    设备树的传递途径
对于Open Firmware (OF)系统,prom_init.c中的代码负责解析设备树,并将其转化为blob印象。

对于无Open Firmware (OF)的系统,内核可以直接从入口启动,并接受外部传递的flattened device tree参数。对于嵌入式系统,此参数由bootloader提供,或者封装过的zImage映像提供。

4.1    U-boot对FDT的支持
U-boot为了支持FDT,专门添加了新的代码,如下:
/Libfdt目录
fdt.h
libfdt.h
fdt_support.h
fdt_support.c

4.2    如何配置FDT
通常在板子配置头文件定义相关宏,以支持FDT
/* Pass open firmware flat tree */
#define CONFIG_OF_LIBFDT    1
#define CONFIG_OF_BOARD_SETUP    1
#define CONFIG_OF_STDOUT_VIA_ALIAS 1

CONFIG_OF_BOARD_SETUP宏表示会对设备树中的部分参数进行调整,主要是timebase-frequency,bus-frequency,clock-frequency等参数,在设备树配置文件中,这些参数可能为0,即采用U-boot中的参数。

4.3    如何传递设备树
Lib_ppc/board.c中do_bootm_linux负责启动Linux内核。
#if defined(CONFIG_OF_LIBFDT)
#include <fdt.h>
#include <libfdt.h>
#include <fdt_support.h>

static void fdt_error (const char *msg);
static int boot_get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
        bootm_headers_t *images, char **of_flat_tree, ulong *of_size);
static int boot_relocate_fdt (struct lmb *lmb, ulong bootmap_base,
        cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
        char **of_flat_tree, ulong *of_size);
#endif

相关流程如下:
 

在该流程中,主要从启动参数中找出设备树,然后在设备树中添加chosen 节点, 并将initrd 的地址地址,结束地址,bootargs,cmd_line 等参数保存到chosen 节点中,最后根据是否支持扁平设备树选择不同的内核启动方式。

#if defined(CONFIG_OF_LIBFDT)
    if (of_flat_tree) {    /* device tree; boot new style */
        /*
         * Linux Kernel Parameters (passing device tree):
         *   r3: pointer to the fdt, followed by the board info data
         *   r4: physical pointer to the kernel itself
         *   r5: NULL
         *   r6: NULL
         *   r7: NULL
         */
        debug ("   Booting using OF flat tree.../n");
        (*kernel) ((bd_t *)of_flat_tree, (ulong)kernel, 0, 0, 0);
        /* does not return */
    } else
#endif
    {
        /*
         * Linux Kernel Parameters (passing board info data):
         *   r3: ptr to board info data
         *   r4: initrd_start or 0 if no initrd
         *   r5: initrd_end - unused if r4 is 0
         *   r6: Start of command line string
         *   r7: End   of command line string
         */
        debug ("   Booting using board info.../n");
        (*kernel) (kbd, initrd_start, initrd_end, cmd_start, cmd_end);
        /* does not return */
    }

如果未定义CONFIG_OF_LIBFDT或者当前bootm命令没有FDT参数时则采用传统的方式启动内核。

启动命令格式如下:
Bootm kernel_addr  ramdisk_addr/-  fdt_addr
当不采用ramdisk时,第二个参数为“-”

5    内核如何解析设备树
1)首先将从u-boot 传递过来的映像基地址和dtb 文件映像基地址保存通用寄存器r30,r31;
2)通过调用machine_init()、early_init_devtree()函数来获取内核前期初始化所需的bootargs,cmd_line等系统引导参数;

3)调用start_kernel()、setup_arch()、unflatten_device_tree()函数来解析dtb 文件,构建一个由device_node 结构连接而成的单项链表,并使用全局变量allnodes 指针来保存这个链表的头指针;
4)内核调用OF 提供的API 函数获取allnodes链表信息来初始化内核其他子系统、设备等。
 

Head_32.S
/*
 * This is where the main kernel code starts.
 */
start_here:
。。。。
/*
 * Do early platform-specific initialization,
 * and set up the MMU.
 */
    mr    r3,r31
    mr    r4,r30
    bl    machine_init

/*
 * Find out what kind of machine we're on and save any data we need
 * from the early boot process (devtree is copied on pmac by prom_init()).
 * This is called very early on the boot process, after a minimal
 * MMU environment has been set up but before MMU_init is called.
 */
void __init machine_init(unsigned long dt_ptr, unsigned long phys)
{
    /* If btext is enabled, we might have a BAT setup for early display,
     * thus we do enable some very basic udbg output
     */
#ifdef CONFIG_BOOTX_TEXT
    udbg_putc = btext_drawchar;
#endif

    /* Do some early initialization based on the flat device tree */
    early_init_devtree(__va(dt_ptr));
}

/* Warning, IO base is not yet inited */
void __init setup_arch(char **cmdline_p)
{
    *cmdline_p = cmd_line;

    /* so udelay does something sensible, assume <= 1000 bogomips */
    loops_per_jiffy = 500000000 / HZ;

    unflatten_device_tree();
…..
}

/**
 * unflattens the device-tree passed by the firmware, creating the
 * tree of struct device_node. It also fills the "name" and "type"
 * pointers of the nodes so the normal device-tree walking functions
 * can be used (this used to be done by finish_device_tree)
 */
void __init unflatten_device_tree(void)
{
    unsigned long start, mem, size;
    struct device_node **allnextp = &allnodes;

    DBG(" -> unflatten_device_tree()/n");

    /* First pass, scan for size */
    start = ((unsigned long)initial_boot_params) +
        initial_boot_params->off_dt_struct;
    size = unflatten_dt_node(0, &start, NULL, NULL, 0);
    size = (size | 3) + 1;

    DBG("  size is %lx, allocating.../n", size);

    /* Allocate memory for the expanded device tree */
    mem = lmb_alloc(size + 4, __alignof__(struct device_node));
    mem = (unsigned long) __va(mem);

    ((u32 *)mem)[size / 4] = 0xdeadbeef;

    DBG("  unflattening %lx.../n", mem);

    /* Second pass, do actual unflattening */
    start = ((unsigned long)initial_boot_params) +
        initial_boot_params->off_dt_struct;
    unflatten_dt_node(mem, &start, NULL, &allnextp, 0);
    if (*((u32 *)start) != OF_DT_END)
        printk(KERN_WARNING "Weird tag at end of tree: %08x/n", *((u32 *)start));
    if (((u32 *)mem)[size / 4] != 0xdeadbeef)
        printk(KERN_WARNING "End of tree marker overwritten: %08x/n",
               ((u32 *)mem)[size / 4] );
    *allnextp = NULL;

    /* Get pointer to OF "/chosen" node for use everywhere */
    of_chosen = of_find_node_by_path("/chosen");
    if (of_chosen == NULL)
        of_chosen = of_find_node_by_path("/chosen@0");

    DBG(" <- unflatten_device_tree()/n");
}

6    设备树对驱动设计产生的影响
TBD

设备树的解析 LibFDT 本文主要介绍 libfdt 以及使用 libfdt 来解析设备树libfdt 可通过安装,但是从内核的中直接提取也是可以直接使用的。因为libfdt不依赖任何 IO 相关的内容。 阅读详情

相关推荐

简析PPC的Device Tree机制

我的理解是为了适应灵活的嵌入式平台,FDT将一些固定人为需要修改的参数信息从uboot和kernel中(如uboot下的bd_t)剥离出来,修改硬件后,不需要重新修改烧录uboot kernel,仅需要修改FDT文件即可完成对新硬件的支持。但是有一些动态修改的信息还是需要uboot以及kernel来操作,如cmdline,usb以及pci的枚举设备信息。

做一个有技术追求的人 3172

linux设备树详解

现在的linux内核(Linux3.X)都已支持设备树机制(dts),不管你是玩内核还是玩驱动,一定会碰到设备树,而网上虽然有很多博客,但都讲的不够清晰,看了还是不懂,半桶水,学员急需一套讲解设备树比较透彻的课程,所以我们来了,致力于帮助广大学员扫清设备树在驱动以及内核学习中的障碍。

设备树的interrupt

设备树的interrupt

【嵌入式Linux学习七步曲之第三篇 Linux系统bootlaoder移植】全面解析PowerPC架构下的扁平设备树FDT

全面解析PowerPC架构下的扁平设备树FDTSailor_forever  sailing_9806#163.com(本原创文章发表于Sailor_forever 的个人blog,未经本人许可,不得用于商业用途。任何个人、媒体、其他网站不得私自抄袭;网络媒体转载请注明出处,增加原文链接,否则属于侵权行为。如有任何问题,请留言或者发邮件给sailing_9806@163.com

Sailor_forever 1万+

STM32 CAN发送丢包?3个邮箱轮询法实测有效(附代码)

本文深入分析了STM32 CAN总线发送丢包的根本原因,指出其内置CAN控制器的三个发送邮箱是硬件瓶颈。针对高负载场景,提供了实测有效的优化方案,重点介绍了非阻塞的邮箱状态轮询法,该方法通过主动轮询三个邮箱的空闲状态,充分利用硬件资源,显著提升发送稳定性并避免任务阻塞。文中附有可直接使用的示例代码。

weixin_29189381的博客 195

FLoRA: 基于异构低秩适应的联邦微调大语言模型

大语言模型(LLMs)的快速发展推动了人工智能的进步,预训练的LLMs可以通过微调适应各种下游任务。联邦学习(FL)通过利用客户端的本地数据进行原位计算,进一步增强了隐私保护的微调,消除了数据移动的需求。然而,考虑到LLMs的巨大参数量,微调LLMs对于资源受限且异构的FL客户端来说是一个挑战。之前的方法采用了低秩适应(LoRA)进行高效的联邦微调,但在LoRA适配器上使用了传统的FL聚合策略。这些方法导致了数学上不准确的聚合噪声,降低了微调效果,并且未能解决异构LoRA的问题。

tiger00O的博客 2065

内核小碎碎-第四集 解析dtb

DTB文件格式如图【图片摘自https://blog.csdn.net/cc289123557/article/details/51782449】 可参考内核的Booting-without-of.txt描述,主要内容如下: a) ATAGS interface. Minimal information is passed from firmware to the kernel with a...

jingshaoyou的博客 419

科研党福音:如何用Zotero+Paper Agent打造你的AI论文速递系统(附详细配置教程)

本文为科研工作者提供了一套利用Zotero和开源工具Paper Agent构建自动化AI论文速递系统的详细教程。该系统能基于用户在Zotero中的文献库智能学习研究兴趣,每日自动从arXiv等平台筛选、下载并深度解读最相关的前沿论文,生成个性化日报,实现从被动接收到主动精准获取的知识工作流重塑。

kite3的博客 514

全面解析PowerPC架构下的扁平设备树FDT(ZT)

Sailor_forever sailing_9806#163.com (本原创文章发表于Sailor_forever 的个人blog,未经本人许可,不得用于商业用途。任何个人、媒体、其他网站不得私自抄袭;网络媒体转载请注明出处,增加原文链接,否则属于侵权行为。如有任何问题,请留言或者发邮件给sailing_9806@163.com) http://blog.csdn.net/sailo...

fanrey123的博客 1124

Vite 任意文件读取漏洞复现(CVE-2026-39363)

Vite开发服务器 WebSocket中的fetchModule方法未实施server.fs访问控制,导致攻击者可通过WebSocket连接并读取服务器上的任意文件(CVE-2026-39363)

iSee857的博客 220

手把手教你学Simulink--进阶电机控制场景实例:基于Simulink的直流电机双闭环调速系统抗负载扰动仿真

摘要:本文基于Simulink平台构建直流电机双闭环调速系统,重点研究其在工业传送带场景下的抗负载扰动性能。系统采用转速外环(稳速)和电流内环(限流)的嵌套结构,通过工程法整定PI参数,实现了转速跌落<10%、恢复时间<0.5s的优异抗扰性能。仿真结果表明,相比单闭环系统,双闭环控制使转速跌落率降低47%,恢复时间缩短75%。文中详细介绍了数学模型建立、Simulink模块实现及参数优化方法,并提供了完整代码和模型文件,为电机控制系统设计提供实用参考。

MHD0815的博客 179

全面解析PowerPC架构下的扁平设备树FDT 、设备树节点DTB

Sailor_forever  sailing_9806#163.com(本原创文章发表于Sailor_forever 的个人blog,未经本人许可,不得用于商业用途。任何个人、媒体、其他网站不得私自抄袭;网络媒体转载请注明出处,增加原文链接,否则属于侵权行为。如有任何问题,请留言或者发邮件给sailing_9806@163.com)http://blog.csdn.net/sailor_8318

LYJ个人博客,记录技术、八卦、生活,分享各种心得,期待与朋友们一同进步 7039

【AI Agent】Hermes Agent解析

Hermes Agent:一个具备持久化学习能力的开源AI Agent框架 核心特点: 突破传统Agent的"无状态困境",通过记忆系统(SQLite+FTS5全文检索)实现跨会话经验积累 支持200+模型自由切换,11种模型家族和15+平台接入 五层架构设计(入口层、编排层、推理层、工具执行层、存储层)实现平台无关性 47+内置工具和动态技能沉淀机制,支持从任务执行中自动提炼可复用Skill 独特的四层记忆体系(会话/每日/长期/向量索引)和辩证式用户建模 与传统Agent对比: 具备自我进化能力,通过A

sysu_lluozh 928

全面解析PowerPC架构下的扁平设备树FDT 、设备树节点DTB .

(本原创文章发表于Sailor_forever 的个人blog,未经本人许可,不得用于商业用途。任何个人、媒体、其他网站不得私自抄袭;网络媒体转载请注明出处,增加原文链接,否则属于侵权行为。如有任何问题,请留言或者发邮件给sailing_9806@163.com) http://blog.csdn.net/sailor_8318/archive/2009/12/26/5078959.aspx

janlie的专栏 869

LLaMA Factory多卡微调的实战教程(持续更新)

本文主要介绍了LLaMA Factory多卡微调的实战教程(持续更新),希望对学习大语言模型的同学们有所帮助。 文章目录 1. 前言 2. 配置环境 2.1 安装虚拟环境 2.2 安装依赖库 2.3 模型选型与下载 2.4 配置多卡环境 3. 运行代码 3.1 构建训练数据 3.2 修改配置文件 3.3 微调 3.3.1 zero3微调 3.3.2 启动API 3.3.3 模型测试

herosunly的博客 25万+

【Unity】【Pico】【VR开发】为何PICO打包后真机运行闪退

由于并没有开版权验证,而且闪退后也并没有弹框说版权问题,所以还是怀疑环境有什么地方不对。设置步骤,项目配置都没问题,Build也成功,Unity版本是符合要求的2022LTS版本,但是一在真机上运行就闪退。

每日出拳老爷子的博客 3175

linux boot设备类型,【嵌入式Linux学习七步曲之第三篇 Linux系统bootlaode

全面解析PowerPC架构下的扁平设备树FDT【摘要】本文以MPC8378处理器、Linux2.6.25内核及U-boot1.3.4为例,讲述了如何在PowerPC架构下使用FDT。首先介绍了引入FDT的背景,接着详细介绍了FDT的组成及制作。最后介绍了U-boot及内核如何支持FDT。【关键字】PowerPC,MPC8378,DTS,DTB,FDT,devicenode,property,com...

weixin_32899685的博客 319

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

嵌入式PowerPC上的扁平设备树FDT

本文在网络上引用甚广,详细的讲述了新版内核dts架构,这里引来详细拜读,本人对原文格式略作调整,原文地址: 嵌入式PowerPC上的扁平设备树FDT 摘 要:设备树的引入减少了内核为支持新硬件而需要的改变,提高代码重用,加速了Linux支持包的开发,使得单个内核镜像能支持多个系统。作为U-Boot和Linux内核之间的动态接口,本文阐述了设备树的数据存储格式以及源码描述语法,进而分

girlkoo的专栏 3827

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

Linux 设备树(Device Tree)概览

本文是一份系统化的 Linux 设备树(Device Tree)学习与实践指南,覆盖从硬件描述思想、语法规范、内核解析机制到驱动开发实战的完整知识体系。

smallerxuan的博客 6955

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

linux设备树dts移植详解

转自:http://blog.csdn.net/cosmoslhf/article/details/9252509 和:  http://www.verydemo.com/demo_c407_i7849.html

haima1998的专栏 1335

嵌入式Linux内核调试实战:从环境搭建到模块调试全解析

在嵌入式系统开发中,内核调试是确保系统稳定运行的关键技术。其核心原理在于通过调试器接管处理器执行流程,实现对内核代码的源码级单步跟踪与状态监控。这项技术的价值在于能够深入系统底层,精准定位启动失败、驱动异常等复杂问题,极大提升开发效率。在基于Power Architecture等处理器的嵌入式Linux开发场景中,内核调试广泛应用于板卡启动、驱动开发和性能优化。本文聚焦于使用CodeWarrior IDE进行嵌入式Linux内核调试的完整流程,详细解析了调试环境构建、内存布局规划、设备树处理等核心环节,并深

weixin_30487201的博客 322

【基于EDK的嵌入式系统】 关于Xilinx EDK添加自定义IP核到PLB总线后linux无法boot的问题

在成功移植Montavista到ML507开发板之后,尝试添加最简单的用户自定义IP核到PLB总线上,自定义IP核包含一个可以访问的wire型寄存器reg0,并给assign reg0 = 32’d1234,同时屏蔽了XPS自动生成的赋值语句。IP核里reg0外设在standalone模式下被成功读取出来。打印结果如下: -- Entering main() -- -- Init LEDs..

DC的陋室 3232

RK3399 驱动开发 _ 04 - Android系统中通过fdt文件系统反编译查看设备中真实生效的设备树配置信息

在根文件系统中查看设备树,是一种不错的调试手段。因为很多时候会出现你修改了 dts 文件,并且也编译了新的 dtb,但是下载到板子上的还是以前的 dtb,因此查看板子中真实生效的设备树配置信息是很重要的。

chenkanuo的博客 1922
上一篇: uImage与zImage的区别
下一篇: MII、RMII、GMII接口的详细介绍
若水心境
博客等级 码龄19年 103粉丝 23原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值