Linux
device tree 정리
반응형
DTS (Device Tree Source) file
arch/arm/boot/dts
.dts : board-level definitions
.dtsi : SoC-level definitions
device tree compiler
scripts/dts
device tree blob
produced by the compiler
passed by the bootloader and parseed at boot time
arch/arm/boot/dts/Makefile
lists which DTSs should be generated at build time
. bootloader의 일
bootload loads (kernel image)
uImage
or
zImage
ATAGS 초기화
memory size, location 등의 정보를 지님
Linux command line 정보를 지님
kernel에게
보드 정보 pass (via r1)
U-boot command
bootm <kernel img addr>
. device tree 이전
----------------------------
| ATAGS | uImage |
----------------------------
r1 = <machine type>
r2 = <pointer to ATAGS>
. device tree 이후
커널은 더이상 hardware description 정보를 지니지 않음
device tree blob이란 binary에 저장되어 있음
bootload는 다음의 2개를 load
1) uImage or zImage
2) DTB (located in arch/arm/boot/dts/) <- one per board
bootloader가
DTB address를 r2로 전달
(memrory information으로 DTB가 조절될 수 있음)
U-boot command
bootm <kernel img addr> - <dtb addr>
----------------------------------
| DTB | | uImage |
----------------------------------
r1 = don't care
r2 = pointer to DTB
. legacy device tree
CONFIG_ARM_APPENDED_DTB option
cat arch/arm/boot/zImage arch/arm/boot/dts/myboard.dtb > my-zImage
mkimage ... -d my-zImage my-uImage
CONFIG_ARM_ATAG_DTB_COMPAT
커널이 ATAGS 정보를 읽고 DT를 update
. Device Tree Syntax
+--- node name
| +- unit address
| |
/ { v v
node@0 {
a-string-property = "A string"; <-- property name = value
a-string-list-prop = "1" "2" "3";
a-byte-data-prop = [0x01 0x02 0x03 0x04];
child-node@0 {
first-child-prop;
second-child-prop = <1>;
a-ref-to-something = <&node1>; <- reference to another node
};
child-node@1 {
};
};
+--- label
|
v
node1: node@1 {
an-empty-prop;
a-cell-prop = <1 2 3 4> <-- four cells (32 bits values)
child-node@0 {
};
};
ex.
auart0: serial@8006a000 {
+--- id used by the OS
|
v
compatible = "fsl,imx28-auart", "fsl,imx23-auart";
reg = <0x8006a000 0x2000>; <- addr & length
interrupts = <112>; <- IRQ number
dmas = <&dma_apbx 8>, <&dma_apbx 9>; <- DMA engine and ch, with names
dma-names = "rx", "tx";
clocks = <&clks 45> <- clk ref.
status = "disabled"; <- dev is not enabled
};
static struct of_device_id mxs_ausrt_dt_ids[] = {
{
.compatible = "fsl,imx28-uart",
.data = "mxs_auart_devtype[IMX28_AUART]
},
{
.compatible = "fsl,imx23-uart",
.data = "mxs_auart_devtype[IMX23_AUART]
},
{
/* sentinel */
}
};
MODULE_DEVICE_TABLE(of, mxs_auart_dt_ids);
[...]
static struct platform_driver mxs_auart_driver = {
.probe = mxs_auart_probe,
.remove = mxs_auart_remove,
.driver = {
.name = "mxs-auart",
.of_match_table = mxs_auart_dt_ids,
},
};
static int mxs_auart_probe(struct platform_device *pdev)
{
const struct of_device_id *of_id =
of_match_device(mxs_auart_dt_ids, &pdev->dev);
if (!of_id) {
....
return....
}
/* use of_id->data here */
s->clk = clk_get(&pdev->dev, NULL);
// getting the I/O register resource
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
s->irq = platform_get_irq(pdev, 0); // get IRQ nr
s->rx_dma_chan = dma_request_slave_channel(s->dev, "rx");
s->tx_dma_chan = dma_request_slave_channel(s->dev, "tx");
// custom property
struct device_node *np = pdev->dev.of_node;
if (of_get_property(np, "fsl,uart-has-rtscts", NULL))
...
}
. device tree inclusion
여러 file로 구성 가능
.dtsi가 .dts file들을 includsion
보통
.dtsi가 SoC-level의 information을 contain
.dts file은 board-level information을 contain
. device tree binding
ref.
Documentation/devicetree/bindings
properties, values에 대한 명시
새로운 binding 추가 시,
devicetree@vger.kernel.org에 post 하여 maintainer에 알려야 함
* Freescale MXS Application UART (AUART)
Required properties:
- compatible : Should be "fsl,<soc>-auart". The supported SoCs include
imx23 and imx28.
- reg : Address and length of the register set for the device
- interrupts : Should contain the auart interrupt numbers
- dmas: DMA specifier, consisting of a phandle to DMA controller node
and AUART DMA channel ID.
Refer to dma.txt and fsl-mxs-dma.txt for details.
- dma-names: "rx" for RX channel, "tx" for TX channel.
Example:
auart0: serial@8006a000 {
compatible = "fsl,imx28-auart", "fsl,imx23-auart";
reg = <0x8006a000 0x2000>;
interrupts = <112>;
dmas = <&dma_apbx 8>, <&dma_apbx 9>;
dma-names = "rx", "tx";
};
Note: Each auart port should have an alias correctly numbered in "aliases"
node.
. device tree organization: top-level nodes
root 밑에는 보통,
cpus ndoe
memory node
chosen node
aliases node
...
one or more nodes defining the buses in he SoC
one or more nodes defining on-board devices
/ {
aliases { ... };
cpus { ... };
apb@80000000 {
apbh@80000000 {
/* Some devices */
};
apbx@80040000 {
/* Some devices */
};
};
ahb@80080000 {
/* Some devices */
};
};
반응형
'Linux' 카테고리의 다른 글
Kinux kernel Bottom half 정리 (softirq, tasklet, workqueue) - part 2 (0) | 2018.03.18 |
---|---|
Linux kernel process (0) | 2018.03.18 |
Linux의 kmalloc과 vmalloc에 대해서 (0) | 2018.03.18 |
Linux kernel: kthread & wait_event_interruptible 사용법 (0) | 2018.03.18 |
process scheduling (0) | 2015.10.02 |
댓글