Device Tree

May Change if some configurations changed.. (ex. more cpu smp etc.)

/dts-v1/;
 
/ {
	interrupt-parent = <0x8002>;
	model = "linux,dummy-virt";
	#size-cells = <0x02>;
	#address-cells = <0x02>;
	compatible = "linux,dummy-virt";
 
	psci {
		migrate = <0xc4000005>;
		cpu_on = <0xc4000003>;
		cpu_off = <0x84000002>;
		cpu_suspend = <0xc4000001>;
		method = "smc";
		compatible = "arm,psci-1.0\0arm,psci-0.2\0arm,psci";
	};
 
	memory@40000000 {
		reg = <0x00 0x40000000 0x01 0x00>;
		device_type = "memory";
	};
 
	platform-bus@c000000 {
		interrupt-parent = <0x8002>;
		ranges = <0x00 0x00 0xc000000 0x2000000>;
		#address-cells = <0x01>;
		#size-cells = <0x01>;
		compatible = "qemu,platform\0simple-bus";
	};
 
	fw-cfg@9020000 {
		dma-coherent;
		reg = <0x00 0x9020000 0x00 0x18>;
		compatible = "qemu,fw-cfg-mmio";
	};
 
	virtio_mmio@a000000 {
		dma-coherent;
		interrupts = <0x00 0x10 0x01>;
		reg = <0x00 0xa000000 0x00 0x200>;
		compatible = "virtio,mmio";
	};
	
	...(생략)
 
	virtio_mmio@a003e00 {
		dma-coherent;
		interrupts = <0x00 0x2f 0x01>;
		reg = <0x00 0xa003e00 0x00 0x200>;
		compatible = "virtio,mmio";
	};
 
	gpio-keys {
		compatible = "gpio-keys";
 
		poweroff {
			gpios = <0x8004 0x03 0x00>;
			linux,code = <0x74>;
			label = "GPIO Key Poweroff";
		};
	};
 
	pl061@9030000 {
		phandle = <0x8004>;
		clock-names = "apb_pclk";
		clocks = <0x8000>;
		interrupts = <0x00 0x07 0x04>;
		gpio-controller;
		#gpio-cells = <0x02>;
		compatible = "arm,pl061\0arm,primecell";
		reg = <0x00 0x9030000 0x00 0x1000>;
	};
 
	pcie@10000000 {
		interrupt-map-mask = <0x1800 0x00 0x00 0x07>;
		interrupt-map = <0x00 0x00 0x00 0x01 0x8002 0x00 0x00 0x00 0x03 0x04 0x00 0x00 0x00 0x02 0x8002 0x00 0x00 0x00 0x04 0x04 0x00 0x00 0x00 0x03 0x8002 0x00 0x00 0x00 0x05 0x04 0x00 0x00 0x00 0x04 0x8002 0x00 0x00 0x00 0x06 0x04 0x800 0x00 0x00 0x01 0x8002 0x00 0x00 0x00 0x04 0x04 0x800 0x00 0x00 0x02 0x8002 0x00 0x00 0x00 0x05 0x04 0x800 0x00 0x00 0x03 0x8002 0x00 0x00 0x00 0x06 0x04 0x800 0x00 0x00 0x04 0x8002 0x00 0x00 0x00 0x03 0x04 0x1000 0x00 0x00 0x01 0x8002 0x00 0x00 0x00 0x05 0x04 0x1000 0x00 0x00 0x02 0x8002 0x00 0x00 0x00 0x06 0x04 0x1000 0x00 0x00 0x03 0x8002 0x00 0x00 0x00 0x03 0x04 0x1000 0x00 0x00 0x04 0x8002 0x00 0x00 0x00 0x04 0x04 0x1800 0x00 0x00 0x01 0x8002 0x00 0x00 0x00 0x06 0x04 0x1800 0x00 0x00 0x02 0x8002 0x00 0x00 0x00 0x03 0x04 0x1800 0x00 0x00 0x03 0x8002 0x00 0x00 0x00 0x04 0x04 0x1800 0x00 0x00 0x04 0x8002 0x00 0x00 0x00 0x05 0x04>;
		#interrupt-cells = <0x01>;
		ranges = <0x1000000 0x00 0x00 0x00 0x3eff0000 0x00 0x10000 0x2000000 0x00 0x10000000 0x00 0x10000000 0x00 0x2eff0000 0x3000000 0x80 0x00 0x80 0x00 0x80 0x00>;
		reg = <0x40 0x10000000 0x00 0x10000000>;
		msi-map = <0x00 0x8003 0x00 0x10000>;
		dma-coherent;
		bus-range = <0x00 0xff>;
		linux,pci-domain = <0x00>;
		#size-cells = <0x02>;
		#address-cells = <0x03>;
		device_type = "pci";
		compatible = "pci-host-ecam-generic";
	};
 
	pl031@9010000 {
		clock-names = "apb_pclk";
		clocks = <0x8000>;
		interrupts = <0x00 0x02 0x04>;
		reg = <0x00 0x9010000 0x00 0x1000>;
		compatible = "arm,pl031\0arm,primecell";
	};
 
	pl011@9000000 {
		clock-names = "uartclk\0apb_pclk";
		clocks = <0x8000 0x8000>;
		interrupts = <0x00 0x01 0x04>;
		reg = <0x00 0x9000000 0x00 0x1000>;
		compatible = "arm,pl011\0arm,primecell";
	};
 
	pmu {
		interrupts = <0x01 0x07 0x04>;
		compatible = "arm,armv8-pmuv3";
	};
 
	intc@8000000 {
		phandle = <0x8002>;
		interrupts = <0x01 0x09 0x04>;
		reg = <0x00 0x8000000 0x00 0x10000 0x00 0x80a0000 0x00 0xf60000>;
		#redistributor-regions = <0x01>;
		compatible = "arm,gic-v3";
		ranges;
		#size-cells = <0x02>;
		#address-cells = <0x02>;
		interrupt-controller;
		#interrupt-cells = <0x03>;
 
		its@8080000 {
			phandle = <0x8003>;
			reg = <0x00 0x8080000 0x00 0x20000>;
			#msi-cells = <0x01>;
			msi-controller;
			compatible = "arm,gic-v3-its";
		};
	};
 
	flash@0 {
		bank-width = <0x04>;
		reg = <0x00 0x00 0x00 0x4000000 0x00 0x4000000 0x00 0x4000000>;
		compatible = "cfi-flash";
	};
 
	cpus {
		#size-cells = <0x00>;
		#address-cells = <0x01>;
 
		cpu-map {
			socket0 {
				cluster0 {
					core0 {
						cpu = <0x8001>;
					};
				};
			};
		};
 
		cpu@0 {
			phandle = <0x8001>;
			reg = <0x00>;
			compatible = "arm,cortex-a76";
			device_type = "cpu";
		};
	};
 
	timer {
		interrupts = <0x01 0x0d 0x04 0x01 0x0e 0x04 0x01 0x0b 0x04 0x01 0x0a 0x04>;
		always-on;
		compatible = "arm,armv8-timer\0arm,armv7-timer";
	};
 
	apb-pclk {
		phandle = <0x8000>;
		clock-output-names = "clk24mhz";
		clock-frequency = <0x16e3600>;
		#clock-cells = <0x00>;
		compatible = "fixed-clock";
	};
 
	chosen {
		stdout-path = "/pl011@9000000";
		rng-seed = <0x45efbb7b 0x6d473e1e 0xc4883b80 0x72c67d86 0x5215531b 0x9cb909a4 0x775c5488 0x864f215b>;
		kaslr-seed = <0x2b1e6ddd 0xe1b43dc9>;
	};
};

Parse DTB from the kernel

  • DTB를 파싱하기 위해서 hermit-dtb 라이브러리를 이용하였다.
  • qemu에서 시뮬레이션할 Virt Board에서는 RAM의 시작주소인 0x40000000에 dtb를 qemu가 로딩해주므로, 해당 주소를 참조하여 dtb를 확인할 수 있었다.

QEMU Device Tree

  • timer: ARM 타이머 관련..
  • intc: GIC 인터럽트 컨트롤러 관련..
  • pl011: standard output 관련..
  • memory: 0x40000000부터 시작되는 사용가능한 메모리공간의 주소
    • 다만, 0x40000000에는 Device Tree가 로딩되어 있으므로, 적당히 0x40200000부터 사용한다.
  • 등등,,

ACPI vs Device Tree

ACPI

  • Advanced Configuration and Power Interface
  • 주로, X86시스템의 Server/PC에서 사용됨
  • ACPI started as an interface between firmware (formerly BIOS) and OS for things like power management, but also things like platform device probing

(Flattened) Device Tree

  • 주로, ARM 기반의 Embedded System에서 사용됨
  • DT was always (even long before ACPI existed) about declarative platform device descriptions (probing and configuration), so the OS can properly initialize all drivers, configure operation points, etc, etc.

Reference