Device-Tree-Tutorial (Zynq)
Zusammenfassung
Fünfteiliges Tutorial von Xillybus zur Linux Device Tree: Beschreibung der Hardware für den Kernel über Daten statt Code. Geschrieben für den Xilinx Zynq-7000 (ARM Cortex-A9 + FPGA), aber die Konzepte gelten allgemein für ARM-Embedded-Linux. Behandelt DTS-Syntax, dtc-Kompilierung, Treiber-Matching über compatible und die Ressourcen-API im Probe-Pfad.
Inhalt
Teil I – Motivation und Werkzeuge
- Problem: ARM-Chips haben keine BIOS-artige Selbstbeschreibung; pro Board eigene Header/Patches führten zu einem „unmaintainable pile of hacks”. Lösung: Device Tree (Open Firmware / Flattened Device Tree, FDT) als Bytestruktur, die der Bootloader vor dem Sprung in den Kernel an eine bekannte RAM-Adresse legt.
- Drei Formen:
.dts(Quelle) →.dtb(Binary Blob) →/proc/device-tree(Dateisystem im laufenden System zum Debuggen). - Kompilieren:
scripts/dtc/dtc -I dts -O dtb -o my-tree.dtb my-tree.dts; Rückübersetzen:-I dtb -O dts; effektiven Tree auslesen:dtc -I fs -O dts ~/effective.dts /proc/device-tree/. - Modularisierung per
#includevon.dtsi: prozessorabhängige Peripherie dort mitstatus = "disabled", board-DTS überschreibt gezielt mit"okay". Da dtc kein#includekennt: kbuild-Makefile mitalways := mydevicetree.dtb(kombinierbar mitobj-mfür den Treiber).
Teil II – Struktur des Baums
- Wurzel
/trägt#address-cells,#size-cells,compatible = "xlnx,zynq-zed",interrupt-parent; typische Kinder:chosen(bootargs,linux,stdout-path),cpus,memory@0(reg = <0x0 0x20000000>), Busaxi@0mitcompatible = "...", "simple-bus". - Analogie Dateisystem: Knoten = Verzeichnisse, Zuweisungen = Dateien;
/proc/device-tree/#size-cellszeigt Integer Big Endian. Labels (ps7_ddr_0:) stehen nicht im DTB. - Boot-Kommandozeile aus drei Quellen möglich:
CONFIG_CMDLINE, Bootloader,chosen/bootargs.
Teil III – Matching zwischen Tree und Treiber
- Faustregel des Autors: „Never write a device driver” – existierenden ähnlichen Treiber kopieren/anpassen.
- Vier Anforderungen: Treiber wird geladen, kennt physische Adressen, kennt Interrupts, liest applikationsspezifische Parameter.
- Matching über
compatible(reiner String-Vergleich):
static struct of_device_id xillybus_of_match[] __devinitdata = {
{ .compatible = "xlnx,xillybus-1.00.a", },
{}
};
MODULE_DEVICE_TABLE(of, xillybus_of_match);
static struct platform_driver xillybus_platform_driver = {
.probe = xilly_drv_probe,
.remove = xilly_drv_remove,
.driver = {
.name = "xillybus",
.owner = THIS_MODULE,
.of_match_table = xillybus_of_match,
},
};- Laden: eingebaute Treiber beim Boot, Module später via modprobe (erfordert
depmod -anach Kopieren nach/lib/modules/<ver>/kernel/drivers/). Mehrere Treiber können matchen; Probe-Reihenfolge undefiniert.
Teil IV – Register und Interrupts im Probe
match = of_match_device(xillybus_of_match, &op->dev);
of_address_to_resource(&op->dev.of_node, 0, &res); /* reg -> res.start/end */
request_mem_region(res.start, resource_size(&res), "xillybus");
registers = of_iomap(op->dev.of_node, 0); /* ≙ ioremap(res) */- Zugriff nur via
iowrite32()/ioread32()– niemals Pointer direkt odervolatile(Cache-Kohärenz auf ARM!). - Interrupts:
irq = irq_of_parse_and_map(op->dev.of_node, 0); request_irq(irq, isr, 0, "xillybus", dev); interrupts = <0 59 1>: (1) SPI-Flag (Konvention: 0), (2) IRQ-Nummer − 32 (GIC-Nummer aus XPS), (3) Typ: 0 = unverändert, 1 = rising edge, 4 = level/high; falling edge/active low werden von der Hardware nicht unterstützt.
Teil V – Eigene Properties
- Custom-Parameter wie
xlnx,slv-awidth = <0x20>;auslesen:ptr = of_get_property(op->dev.of_node, "xlnx,slv-awidth", NULL); value = be32_to_cpup(ptr);(Big Endian → CPU-Endianness; weitere API indrivers/of/base.c). - Checkliste für ein eigenes IP-Peripherie-Entry:
compatible-String wählen,regaus XPS-Adressmap eintragen,interrupt-parent = <&gic>,interruptssetzen, Custom-Parameter ergänzen.
Kernkonzepte
compatibleverbindet Hardware-Knoten mit Treiber;reg/interruptsbeschreiben Ressourcen;#address-cells/#size-cellssteuern das Adressformat.dtcübersetzt DTS ⇄ DTB;/proc/device-treemacht den aktiven Baum sichtbar.
Quellen
raw/Device-Tree I.pdf…raw/Device-Tree V.pdf– Tutorial-Teile 1–5 (Xillybus)