On Sun, Apr 3, 2011 at 4:38 AM, Andy Green andy@warmcat.com wrote:
On 04/03/2011 04:07 AM, Somebody in the thread at some point said:
Hi -
* And very hardware specific code moved out to a controllable place, i.e. something like BIOS
Sorry, but I must vehemently disagree here. BIOSes are a problem for Open Source, not a solution. On X86 they use BIOS services only when there is simply no other choice, because the BIOS is too often buggy and it is more difficult and risky to update than the kernel.
I followed the lkml thread and saw there bootloaders mentioned as some kind of happy place all problems will be solved. You're quite right it's just a carpet to shove stuff under and stumble over.
If the kernel operation will intimately rely on this information, eg DT tables, and needs its versioning to match kernel code precisely, in the end it can't avoid owning it and that extends up to packaging as well. The "attach device tree data to end of kernel" scheme you mentioned, or taking it inside the kernel tree seems the way to go in that domain not indirecting its availability and versioning through not only bootloader package, code but also environment.
I've worked on DT based PowerPC systems which have similar, multiple variants of the base hardware. The bootloader provides the DT to the kernel on these machines. A unified kernel image reads the DT and then adjusts to reflect the hardware specified in the device tree.
Think of the DT as a way of probing a bus that doesn't have probe capabilities. This gives you a way to dynamically load drivers from initrd if you want. For example we dynamically loaded drivers for I2C devices that were previously always built in.
Board specific code inside the kernel can trigger off the DT board name and then deal with variations of DT formats that exist for that particular board so you aren't forced to update the kernel and DT in lock step. Examples of that are in arch/powerpc/platforms/xxx/board-x Code in there looks for some old, messed up DTs and then modifies them to be compliant before allowing the kernel to read them. If the user updates their bootloader/DT that code won't trigger. The trick here is that the code modifies the DT, and then the kernel interprets the DT. The code detecting the old DT format does not go and directly manipulate the device drivers.
The goal of this was to be able to ship single kernel image update that worked on a dozen hardware variations.
I haven't been following the ARM DT work, but a scheme that might work on ARM is to build DTs into the kernel corresponding to each ARM machine ID supported by the kernel image. Use the machine ID to select the correct one and discard the rest. As ARM bootloaders are modified to directly support DTs slowly get rid of the in-kernel DTs.
A key concept: think of the DT as a way of probing a bus that doesn't have probe capabilities. You can argue that C code can produce the same effect as DTs which is true. But that board specific setup code tends to grow and stick its fingers into everything. DTs mitigate that simply because they aren't C code. DTs encourage the development of generic device setup code instead of one-off platform specific code.