为AM335x移植Linux内核主线代码
六、booting-without-of.txt学习笔记(下)
当然,也是因为开源世界的教程类的东东很少,还是老老实实的读README或者Documents吧! ================================================================== III) - Required content of the device tree
WARNING: All "linux,*" properties defined in this documents apply only to a flattened device-tree. If your platform uses a real implementation of Open Firmware or an implementation compatible with the Open Firmware client interface, those properties will be created by the trampoline code in the kernel's prom_init() file. For example, that's where you'll have to add code to detect your board model and set the platform number. However, when using the flattened device-tree entry point, there is no prom_init() pass, and thus you have to provide those properties yourself.
*********************************************************** 练习:什么是Open Firmware? 答:Open Firmware, or OpenBoot in Sun Microsystems parlance, is a standard defining the interfaces of a computer firmware system, formerly endorsed by the Institute of Electrical and Electronics Engineers (IEEE). It originated at Sun, and has been used by Sun, Apple, IBM, and most other non-x86 PCI chipset verdors. Open Firmware allows the system to load platform-independent drivers directly from the PCI card, improving compatibility. --from http://en.wikipedia.org/wiki/Open_Firmware 当然,我用的AM335x平台没有使用Open Firmware,实际上AM335x都不支持PCI协议。所以这个flattened device-tree里面,不能使用Open Firmware定义的硬件啦,我需要自己添加像board model或者platform number这样的参数进去。 *********************************************************** 1) Note about cells and address representation
The general rule is documented in the various Open Firmware documentations. If you choose to describe a bus with the device-tree and there exist an OF bus binding, then you should follow the specification. However, the kernel does not require every single device or bus to be described by the device tree.
In general, the format of an address for a device is defined by the parent bus type, based on the #address-cells and #size-cells properties. Note that the parent's parent definitions of #address-cells and #size-cells are not inherited so every node with children must specify them. The kernel requires the root node to have those properties defining addressed format for devices directly mapped on the processor bus.
Those 2 properties define 'cells' for representing an address and a size. A 'cell' is a 32-bit number. For example, if both contain 2 like the example tree given above, then an address and a size are both composed of 2 cells,and each is a 64-bit number (cells are concatenated and expected to be in big endian format). Another example is the way Apple firmware defines them, with 2 cells for an address and one cell for a size. Most 32-bit implementation should define #address-cells and #size-cells to 1, which represents a 32-bit value. Some 32-bit processors allow for physical addresses greater than 32 bits; these processors should define #address-cells as 2. *********************************************************** 练习:观察am33xx.dtsi的#address-cells和#size-cells。 *********************************************************** "reg" properties are always a tuple of the type "address size" where the number of cells of address and size is specified by the bus #address-cells and #size-cells. When a bus supports various address spaces and other flags relative to a given address allocation (like prefetchable, etc) those flags are usually added to the top level bits of the physical address. For example, a PCI physical address is made of 3 cells, the bottom two containing the actual address itself while the top cell contains address space indication, flags, and pci bus & device numbers.
*********************************************************** 练习:找一找各种各样的#address-cells和#size-cells定义。 *********************************************************** For buses that support dynamic allocation, it's the accepted practice to then not provide the address in "reg" (keep it 0) though while providing a flag indicating the address is dynamically allocated, and then, to provide a separate "assigned-addressed" property that contains the fully allocated addresses. See the PCI OF binding for details.
*********************************************************** 练习:如果动态申请reg应该怎么办? (这块的含义有些难以理解,待研究。) *********************************************************** 2) Note about "compatible" properties
These properties are optional, but recommended in devices and the root node. The format of a "compatible" property is a list of concatenated zero terminated strings. They allow a device to express its compatibility with a family of similar devices, in some cases, allowing a single driver to match against several devices regardless of their actual names.
3) Note about "name" properties
While earlier users of Open Firmware like Oldworld macintoshes tended to use the actual device name for the "name" property, it's nowadays considered a good practice to use a name that is closer to the device class (often equal to device_type). For example, nowadays, Ethernet controllers are named "ethernet", an additional "model" property defining precisely the chip type/model, and "compatible" property defining the family in case a single driver can driver more than one of these chips. However, the kernel doesn't generally put any restriction on the "name" property; it is simply considered good practice to follow the standard and its evolutions as closely as possible.
Note also that the new format version 16 makes the "name" property optional. If it's absent for a node, then the node's unit name is then used to reconstruct the name. That is, the part of the unit name before the "@" sign is used (or the entire unit name if no "@" sign is present). 4) Note about node and property names and character set
While Open Firmware provides more flexible usage of 8859-1, this specification enforces more strict rules. Nodes and properties should be comprised only of ASCII characters 'a' to 'z', '0' to '9', ',', '.', '_', '+', '#', '?', and '-'. Node names additionally allow uppercase characters 'A' to 'Z' (property names should be lowercase. The fact that vendors like Apple don't respect this rule is irrelevant here). Additionally, node and property names should always begin with a character in the range 'a' to 'z' (or 'A' to 'Z' for node names).
The maximum number of characters for both nodes and property names is 31. In the case of node names, this is only the leftmost part of a unit name (the pure "name" property), it doesn't include the unit address which can extend beyond that limit.
*********************************************************** 练习:尝试一下不同的node或者property names。 实际上即使在name或者property names里面使用大写字母也不会报错,即使超过了31个字符也不会报错。Anyway,遵守语法规则总是没错的^_^! *********************************************************** 5) Required nodes and properties
These are all that are currently required. However, it is strongly recommended that you expose PCI host bridges as documented in the PCI binding to Open Firmware, and your interrupt tree as documented in OF interrupt tree specification.
a) The root node
The root node requires some properties to be present:
- model: This is your board name/model - #address-cells: address representation for "root" devices - #size-cells: the size representation for "root" devices - compatible: the board "family" generally finds its way here, for example, if you have 2 board models with a similar layout, that typically get driven by the same platform code in the kernel, you would specify the exact board model in the compatible property followed by an entry that represents the SoC model. The root node is also generally where you add additional properties specific to your board like the serial number if any, that sort of thing. It is recommended that if you add any "custom" property whose name may clash with standard ones, you prefix them with your vendor name and a comma.
*********************************************************** 练习:观察一下AM335x的root节点。
/ { model = "TI AM335x maria_am335x"; compatible = "ti,maria_am335x", "ti,am33xx"; }; / { compatible = "ti,am33xx"; interrupt-parent = <&intc>; }; / { #address-cells =; #size-cells =; chosen { }; aliases { }; memory { device_type = "memory"; reg =; }; };
这三条root节点分别来自: maria_am335x-common.dtsi am33xx.dtsi skeleton.dtsi 它们被maria_am335x.dts以各种不同的层次include。参考本系列的第一篇中关于include的规则,当最顶层定义了从未定义过的property时,则把这项添加进入;当最顶层定义了底层定义过的property时,则更新成最顶层的定义。所以,将上面的root节点整理一下就是下面这个 样子: / { model = "TI AM335x maria_am335x"; compatible = "ti,maria_am335x", "ti,am33xx"; interrupt-parent = <&intc>; #address-cells =; #size-cells =; chosen { }; aliases { i2c0 = &i2c0; /* ... */ }; memory { device_type = "memory"; reg =; }; }; 这样,root节点就和文档里面对应起来了! *********************************************************** b) The /cpus node
This node is the parent of all individual CPU nodes. It doesn't have any specific requirements, though it's generally good practice to have at least:
#address-cells = #size-cells =
This defines that the "address" for a CPU is a single cell, and has no meaningful size. This is not necessary but the kernel will assume that format when reading the "reg" properties of a CPU node, see below
c) The /cpus/* nodes
So under /cpus, you are supposed to create a node for every CPU on the machine. There is no specific restriction on the name of the CPU, though it's common to call it,. For example, Apple uses PowerPC,G5 while IBM users PowerPC,970FX. However, the Generic Names convention suggests that is would be better to simply use 'cpu' for each node and use the compatible property to identify the specific cpu core.
Required properties"
- device_type: has to be "cpu" - reg: This is the physical CPU number, it's a single 32-bit cell and is also used as-is as the unit number for constructing the unit name in the full path. For example, with 2 CPUs, you would have the full path: /cpus/PowerPC,970FX@0 /cpus/PowerPC,970FX@1 (unit addresses do not require leading zeroes) - d-cache-block-size: one cell, L1 data cache block size in bytes (*) - i-cache-block-size: one cell, L1 instruction cache block size in bytes - d-cache-size: one cell, size of L1 data cache in bytes - i-cache-size: one cell, size of L1 intruction cache in bytes (*) The cache "block" size is the size on which the cache management instructions operate. Historically, this document used the cache "line" size here which is incorrect. The kernel will prefer the cache block size and will fallback to line size for backward compatibility.
Recommended properties:
- timebase-frequency: a cell indicating the frequency of the timebase in Hz. This is not directly used by the generic code, but you are welcome to copy/paste the pSeries code for setting the kernel timebase/decrementer calibration based on this value. - clock-frequency: a cell indicating the CPU core clock frequency in Hz. A new property will be defined for 64-bit values, but if your frequency is < 4GHz, one cell is enough. Here as well as for the above, the common code doesn't use that property, but you are welcome to re-use the pSeries or Maple one. A future kernel version might provide a common function for this. - d-cache-line-size: one cell, L1 data cache line size in bytes if different from the block size - i-cache-line-size: one cell, L1 instruction cache line size in bytes if different from the block size You are welcome to add any property you find relevant to your board, like some information about the mechanism used to soft-reset the CPUs. For example, Apple puts the GPIO number for CPU soft reset lines in there as a "soft-reset" property since they start secondary CPUs by soft-resetting them.
*********************************************************** 练习:观察一下AM335x的cpus节点。 直接上整理好的结果: cpus { #address-cells =; #size-cells =; cpu@0 { cpu0-supply = <&dcdc2_reg>; campatible = "arm,cortex-a8"; device_type = "cpu"; reg =; operation-points = < /* kHz uV*/ 720000 1285000 600000 1225000 500000 1125000 275000 1125000 >; voltage-tolerance =; clocks = <&dpll_mpu_ck>; clock-names = "cpu"; clock-latency =; }; }; *********************************************************** d) the /memory node(s)
To define the physical memory layout of your board, you should create one or more memory node(s). You can either create a single node with all memory ranges in its reg property, or you can create several nodes, as you wish. The unit address (@ part) used for the full path is the address of the first range of memory defined by a given node. If you use a single memory node, this will typically be @0.
- device_type: has to be "memory" - reg: This property contains all the physical memory ranges of your board. It's a list of addresses/sizes concatenated together, with the number of cells of each defined by the #address-cells and #size-cells of the root node. For example, with both of these properties being 2 like in the example given earlier, a 970 based machine with 6Gb of RAM could typically have a "reg" property here that looks like: 00000000 00000000 00000000 80000000 00000001 00000000 00000001 00000000 That is a range starting at 0 of 0x80000000 bytes and a range starting at 0x10000000 and of 0x10000000 bytes. You can see that there is no memory covering the IO hole between 2Gb and 4Gb. Some vendors prefer splitting those ranges into smaller segments, but the kernel doesn't care. *********************************************************** 练习:观察一下memory节点。 直接上整理好的结果: memory { device-type = "memory"; reg =; }; ***********************************************************
e) The /chosen node f) the /socnode
This node is used to represent a system-on-chip (SoC) and must be present if the processor is SoC. The top-level soc node contains information that is global to all devices on the SoC. The node name should contain a unit address for the SoC, which is the base address of the memory-mapped register set for the SoC. The name of an SoC node should start with "soc", and the remainder of the name should represent the part number for the soc. For example, the MPC8540's soc node would be called "soc8540".
*********************************************************** 练习:观察一下soc节点。 直接上整理好的结果: soc { compatible = "ti,omap-infra"; mpu { compatible = "ti,omap3-mpu"; ti,hwmods = "mpu"; }; };
*********************************************************** http://forum.eepw.com.cn/thread/262788/1