Converting MIPS to Device Tree
Over the past few days I've started to convert arch/mips to use DT. So far none of the platforms (except maybe PowerTV?) seems to have a firmware that is passing a DT nor is there any 2nd stage bootloader that could do so.
So as the 2nd best thing I've been working on .dts files to be compiled into the images.
I've put a git tree of my current working tree online. It's absolutely work in progress so expect to encounter bugs.
http://git.linux-mips.org/?p=linux-dt.git;a=summary (Gitweb)
git://git.linux-mips.org/linux-dt.git
http://www.linux-mips.org/wiki/Device_Tree (brief documentation & links)
An incomplete to do list:
o Sort out interface for firmware to pass a DT to the kernel. Because we have so many different firmware implementations this one might get a slight bit interesting.
o Interface to select one of several builtin DT images. I am thinking of extending the existing MIPS_MACHINE() / machtype mechanism to play nicely with DT.
o Finish and test AR7, Cobalt, Jazz, Malta, MIPSsim and SNI ports.
o Convert the remaining platforms; find if it's actually sensible to convert all platforms.
o I'm considering to make DT support a requirement for future MIPS platforms so you might as well start beating your firmware monkeys / ask Santa to put you a shiny new bootloader blob into the boot now.
o Write more of the required infrastructure.
o Write documentation
Contributions and comments welcome,
Ralf
Quoted 1 line · Ralf Baechle
Over the past few days I've started to convert
arch/mipsto use DT.
Nice!
Quoted 4 lines
So
far none of the platforms (except maybe PowerTV?) seems to have a firmware that is passing a DT nor is there any 2nd stage bootloader that could do so.
FWIW, U-Boot now has pretty generic support for manipulating and passing a dtb at boot. That doesn't do much good for existing deployed systems though.
Quoted 10 lines
So as the 2nd best thing I've been working on .dts files to be compiled into the images.
I've put a git tree of my current working tree online. It's absolutely work in progress so expect to encounter bugs.
http://git.linux-mips.org/?p=linux-dt.git;a=summary (Gitweb)
git://git.linux-mips.org/linux-dt.git
http://www.linux-mips.org/wiki/Device_Tree (brief documentation & links)
Quoted 5 lines
An incomplete to do list:
o Sort out interface for firmware to pass a DT to the kernel. Because we have so many different firmware implementations this one might get a slight bit interesting.
I strongly recommend defining a single method for passing the DT here.
If firmware is being modified anyway to add DT support, then may as
well get everyone to conform to the same interface. Things do get really hairy if you try to pass the DT inside a legacy firmware interface and then try to figure out which data is authoritative; the dtb or the legacy data. DT boot can even be made a different boot mode for the firmware. This is effectively what U-Boot has done. Either you boot without DT, using the legacy interface, or you boot with DT using a new *and common* DT boot interface.
Quoted 3 lines
o Interface to select one of several builtin DT images. I am thinking of extending the existing
MIPS_MACHINE()/ machtype mechanism to play nicely with DT.
I'm toying with this idea on arm too with the machine_desc structure, but it is looking more likely that ARM is going to support DT on older non-DT firmware by appending the .dtb blob to the zImage, and getting the wrapper to handle fixing up the boot interface. There are patches on the list for this, but they need one more going over before they get committed.
Quoted 10 lines
o Finish and test AR7, Cobalt, Jazz, Malta, MIPSsim and SNI ports.
o Convert the remaining platforms; find if it's actually sensible to convert all platforms.
o I'm considering to make DT support a requirement for future MIPS platforms so you might as well start beating your firmware monkeys / ask Santa to put you a shiny new bootloader blob into the boot now.
o Write more of the required infrastructure.
o Write documentationContributions and comments welcome,
Cheers,
g.
Signature · 2 lines
Grant Likely, B.Sc., P.Eng. Secret Lab Technologies Ltd.
Quoted 5 lines · Grant Likely
Quoted 1 line · Ralf Baechle
Over the past few days I've started to convert
arch/mipsto use DT.Nice!
Quoted 8 lines
Quoted 4 lines
So
far none of the platforms (except maybe PowerTV?) seems to have a firmware that is passing a DT nor is there any 2nd stage bootloader that could do so.FWIW, U-Boot now has pretty generic support for manipulating and passing a dtb at boot. That doesn't do much good for existing deployed systems though.
I took a look at the issue of passing device trees to the kernel and started by surveying the methods currently in use for passing information from the bootloader to the kernel. I came up with the ten approaches:
How MIPS Bootloaders Pass Information to the Kernel
---------------------------------------------------
Apologies for any errors; this was meant more to be a quick survey rather than a detailed analysis.
1. a0 - argc
a1 - argv
Strings are concatenated to create the command line, starting at argv[0].
Platforms: ath79
2. a0 - argc
a1 - argv
a2 - envp
Strings are concatenated to create the command line, starting at argv[0].
Platforms: pnx8550, rb532
3. a0 - argc
a1 - argv Command line created by concatenating argv strings, starting at argv[1]. Platforms: emma, fw, jz4740, lasat, pnx833x, vr41xx
4. a0 - argc
a1 - argv
a2 - envp
Command line created by concatenating argv strings, starting at argv[1].
Platforms: alchemy, ar7, loongson, mti-malta, pmc-sierra
5. a0 - unused
a1 - unused
a2 - unused
Boot descriptor in a3.
Platforms: cavium-octeon
6. a0 - argc
a1 - argv
a2 - non-standard envp
Command line created by concatenating argv strings, starting at argv[1]. The envp is a pointer to a list of char ptr to name/char ptr pairs.
Platforms: txx9
7. a0 - argc
a1 - argv
a2 - magic
a3 - prom_vec
Command line created by concatenating argv strings, starting at either argv[1] or argv[2], depending on the value passed in magic.
Platforms: dec
8. a0 - argc
a1 - unused
a2 - envp
a3 - prom_vec
Interpretation depends on the values passed, but command line is a single string in the cfe environment.
Platforms: bcm47xxx, sibyte
9. a0 - bits 30-16: memory size, bits 15-0, argc
a1 - argv
Command line created by concatenating argv strings, starting at argv[1].
Platforms: cobalt
10. a0 - argc
a1 - argv
a2 - unused
a3 - memory size
The command line is assumed to already be a single string, pointed to by argv.
Platforms: powertv
It seems like everything ultimately does create a command line. We could then use a parameter like "devtree=<virtual-address>" on the command line, passed in any way the bootloader likes. In this case, the <virtual-address> will be a kseg0 address so we don't have to set up any mappings. If we allow multiple device trees to be built in or appended to the end of the kernel, we can use the existing "dtb_compat" command line parameter to select which one to use. I would propose that "devtree" take precedence over "dtb_compat", but that's really just a desire to pick one over the other, whichever is the preferred one.
Signature · 1 line
David VL
Quoted 24 lines · David VomLehn
Quoted 5 lines · Grant Likely
Quoted 1 line · Ralf Baechle
Over the past few days I've started to convert
arch/mipsto use DT.Nice!
Quoted 8 lines
Quoted 4 lines
So
far none of the platforms (except maybe PowerTV?) seems to have a firmware that is passing a DT nor is there any 2nd stage bootloader that could do so.FWIW, U-Boot now has pretty generic support for manipulating and passing a dtb at boot. That doesn't do much good for existing deployed systems though.
I took a look at the issue of passing device trees to the kernel and started by surveying the methods currently in use for passing information from the bootloader to the kernel. I came up with the ten approaches:
How MIPS Bootloaders Pass Information to the Kernel
---------------------------------------------------
Apologies for any errors; this was meant more to be a quick survey rather than a detailed analysis.
[...]
Quoted 7 lines
5. a0 - unused
a1 - unused
a2 - unused
Boot descriptor in a3.
Platforms: cavium-octeon
I have augmented the boot descriptor with a field that contains the *physical* address of the DTB.
[...]
Quoted 11 lines
10. a0 - argc
a1 - argv
a2 - unused
a3 - memory size
The command line is assumed to already be a single string, pointed to by argv.
Platforms: powertvIt seems like everything ultimately does create a command line. We could then use a parameter like "devtree=<virtual-address>" on the command line, passed in any way the bootloader likes.
Some u-boots for non-mips platforms pass it in the environment of the bootm protocol.
I would say to pass the pointer to the DTB in the environment, but not all platforms (like powertv) have an environment. So I guess the command line has to do.
Also I think we should pass the physical address of the DTB, not the virtual address. It would be the kernel's responsibility to figure out what the virtual address is.
David Daney
Quoted 7 lines
In this case, the<virtual-address> will be
a kseg0 address so we don't have to set up any mappings. If we allow multiple device trees to be built in or appended to the end of the kernel, we can use the existing "dtb_compat" command line parameter to select which one to use. I would propose that "devtree" take precedence over "dtb_compat", but that's really just a desire to pick one over the other, whichever is the preferred one.
Quoted 4 lines · David Daney
Quoted 3 lines · David VomLehn
Quoted 2 lines · Grant Likely
Quoted 1 line · Ralf Baechle
Over the past few days I've started to convert
arch/mipsto use DT.
...
Quoted 3 lines
Quoted 3 lines
It seems like everything ultimately does create a command line. We could then use a parameter like "devtree=<virtual-address>" on the command line, passed in any way the bootloader likes.
...
Quoted 3 lines
I would say to pass the pointer to the DTB in the environment, but not all platforms (like powertv) have an environment. So I guess the command line has to do.
[Actually, PowerTV *could* have an environment; I fought with my bootloader people to ensure a2 was NULL to allow for future support for passing a pointer to an environment later. I really wish those guys were in the same group as the kernel people...]
I think we're kind of stuck with passing something on the command line, which means passing the command line in the device tree ends up being a bit confusing. We might want to think about this case a bit:
o Do we take only the device tree argument from the command line, then replace it with the command line in the device tree, if any?
o Or append the device tree command line to the command line?
o Or do something else entirely?
I'm reluctant to leave it undefined but don't really see one alternative as clearly better than another.
Quoted 3 lines
Also I think we should pass the physical address of the DTB, not the virtual address. It would be the kernel's responsibility to figure out what the virtual address is.
I'm good with this. We're currently passing a virtual address with the command line parameter "devicetree" so, not surprisingly, I'd like to use some other parameter name if we pass the physical address. Using "devtree" is nice and short. Or "device_tree" if you like something more less terse.
Quoted 9 lines
David Daney
Quoted 7 lines
In this case, the<virtual-address> will be
a kseg0 address so we don't have to set up any mappings. If we allow multiple device trees to be built in or appended to the end of the kernel, we can use the existing "dtb_compat" command line parameter to select which one to use. I would propose that "devtree" take precedence over "dtb_compat", but that's really just a desire to pick one over the other, whichever is the preferred one.
Any thoughts on precedence of "devtree"/"device_tree" over "dtb_compat"? My thought is that something passed explicitly should take precedence over something built-in, but that's just what I think right now.
Signature · 1 line
David VL
Quoted 9 lines · David VomLehn
I took a look at the issue of passing device trees to the kernel and started by surveying the methods currently in use for passing information from the bootloader to the kernel. I came up with the ten approaches:
How MIPS Bootloaders Pass Information to the Kernel
---------------------------------------------------
Apologies for any errors; this was meant more to be a quick survey rather than a detailed analysis.
Quoted 7 lines
6. a0 - argc
a1 - argv
a2 - non-standard envp
Command line created by concatenating argv strings, starting at argv[1]. The envp is a pointer to a list of char ptr to name/char ptr pairs.
Platforms: txx9
This depends on the actual boot loader. My rbtx4927 has a VxWorks boot loader, which just doesn't pass anything.
Cfr. commit 97b0511ce125b0cb95d73b198c1bdbb3cebc4de2 ("MIPS: TXx9:
Make firmware parameter passing more robust").
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]
In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
Quoted 19 lines · On Wednesday 08 June 2011 09:15:14 Geert Uytterhoeven wrote:
Quoted 10 lines · David VomLehn
I took a look at the issue of passing device trees to the kernel and started by surveying the methods currently in use for passing information from the bootloader to the kernel. I came up with the ten approaches:
How MIPS Bootloaders Pass Information to the Kernel
---------------------------------------------------
Apologies for any errors; this was meant more to be a quick survey rather than a detailed analysis.Quoted 7 lines
6. a0 - argc
a1 - argv
a2 - non-standard envp
Command line created by concatenating argv strings, starting at argv[1]. The envp is a pointer to a list of char ptr to name/char ptr pairs.
Platforms: txx9
Quoted 5 lines
This depends on the actual boot loader. My rbtx4927 has a VxWorks boot loader, which just doesn't pass anything.
Cfr. commit
97b0511ce125b0cb95d73b198c1bdbb3cebc4de2("MIPS: TXx9:
Make firmware parameter passing more robust").
Actually most devices out there OpenWrt is dealing with are in this situation. Most of the time because the boot loader was highly hacked and/or locked down.
In the best cases we can get the bootloader to pass a valid command-line to the kernel.
--
Florian
Quoted 5 lines · Ralf Baechle
Over the past few days I've started to convert
arch/mipsto use DT. So far none of the platforms (except maybe PowerTV?) seems to have a firmware that is passing a DT nor is there any 2nd stage bootloader that could do so.
Quoted 9 lines
So as the 2nd best thing I've been working on .dts files to be compiled into the images.
I've put a git tree of my current working tree online. It's absolutely work in progress so expect to encounter bugs.
http://git.linux-mips.org/?p=linux-dt.git;a=summary (Gitweb)
git://git.linux-mips.org/linux-dt.git
should be git://git.linux-mips.org/pub/scm/linux-dt.git
tonyliu@tonyliu-laptop:/opt/git-root$ git clone git://git.linux-mips.org/linux-dt.git dt-linux_mips Initialized empty Git repository in /opt/git-root/dt-linux_mips/.git/ fatal: The remote end hung up unexpectedly tonyliu@tonyliu-laptop:/opt/git-root$ git clone git://git.linux-mips.org/pub/scm/linux-dt.git dt-linux_mips Initialized empty Git repository in /opt/git-root/dt-linux_mips/.git/ remote: Counting objects: 2448486, done. remote: Compressing objects: 100% (446507/446507), done. Receiving objects: 0% (14786/2448486), 5.26 MiB | 7 KiB/s Receiving objects: 0% (18463/2448486), 6.56 MiB | 12 KiB/s Receiving objects: 2% (67572/2448486), 24.25 MiB | 11 KiB/s Receiving objects: 100% (2448486/2448486), 611.83 MiB | 309 KiB/s, done. remote: Total 2448486 (delta 2040537), reused 2388725 (delta 1982106) Resolving deltas: 100% (2040537/2040537), done. Checking out files: 100% (36749/36749), done.
Tony
Quoted 25 lines
http://www.linux-mips.org/wiki/Device_Tree (brief documentation& links)
An incomplete to do list:
o Sort out interface for firmware to pass a DT to the kernel. Because we have so many different firmware implementations this one might get a slight bit interesting.
o Interface to select one of several builtin DT images. I am thinking of extending the existingMIPS_MACHINE()/ machtype mechanism to play nicely with DT.
o Finish and test AR7, Cobalt, Jazz, Malta, MIPSsim and SNI ports.
o Convert the remaining platforms; find if it's actually sensible to convert all platforms.
o I'm considering to make DT support a requirement for future MIPS platforms so you might as well start beating your firmware monkeys / ask Santa to put you a shiny new bootloader blob into the boot now.
o Write more of the required infrastructure.
o Write documentationContributions and comments welcome,
Ralf
Signature · 6 lines
Tony Liu | Liu Bo ------------------------------------------------------------- WIND RIVER | China Development Center Tel: 86-10-8477-8542 ext: 8542 | Fax: 86-10-64790367 (M): 86-136-7117-3612 Address: 15/F, Wangjing TowerB, Chaoyang District, Beijing, P.R.China
Quoted 9 lines · David Daney
Quoted 2 lines
use a parameter like "devtree=<virtual-address>" on the command line, passed in any way the bootloader likes.
Some u-boots for non-mips platforms pass it in the environment of the bootm protocol.
I would say to pass the pointer to the DTB in the environment, but not all platforms (like powertv) have an environment. So I guess the command line has to do.
3 steps:
1) Use command line argument for DT
2) Iff 1) fails, use DT specified by environment
3) Iff 1) and 2) fail, use builtin DTB.
Quoted 3 lines
Also I think we should pass the physical address of the DTB, not the virtual address. It would be the kernel's responsibility to figure out what the virtual address is.
I like the basic idea - but ... Most firmware will only use KSEG0 / XKPHYS mappings so there should be no aliasing issue but still there could be conflicting cache modes. So we should also specify that firmware should writeback and invalidate the DTB from caches.
Ralf
Quoted 8 lines · Ralf Baechle
Quoted 6 lines · David Daney
Quoted 2 lines
use a parameter like "devtree=<virtual-address>" on the command line, passed in any way the bootloader likes.
Some u-boots for non-mips platforms pass it in the environment of the bootm protocol.
Quoted 8 lines
Quoted 3 lines
I would say to pass the pointer to the DTB in the environment, but not all platforms (like powertv) have an environment. So I guess the command line has to do.
3 steps:
1) Use command line argument for DT
2) Iff 1) fails, use DT specified by environment
I'm OK with this as long as we can define 'the environment' to include what I am currently doing on Octeon.
Quoted 13 lines
3) Iff 1) and 2) fail, use builtin DTB.
Quoted 3 lines
Also I think we should pass the physical address of the DTB, not the virtual address. It would be the kernel's responsibility to figure out what the virtual address is.
I like the basic idea - but ... Most firmware will only use KSEG0 / XKPHYS mappings so there should be no aliasing issue but still there could be conflicting cache modes. So we should also specify that firmware should writeback and invalidate the DTB from caches.
Ralf
Quoted 19 lines · On Wednesday 08 June 2011 09:15:14 Geert Uytterhoeven wrote:
Quoted 10 lines · David VomLehn
I took a look at the issue of passing device trees to the kernel and started by surveying the methods currently in use for passing information from the bootloader to the kernel. I came up with the ten approaches:
How MIPS Bootloaders Pass Information to the Kernel
---------------------------------------------------
Apologies for any errors; this was meant more to be a quick survey rather than a detailed analysis.Quoted 7 lines
6. a0 - argc
a1 - argv
a2 - non-standard envp
Command line created by concatenating argv strings, starting at argv[1]. The envp is a pointer to a list of char ptr to name/char ptr pairs.
Platforms: txx9
Quoted 5 lines
This depends on the actual boot loader. My rbtx4927 has a VxWorks boot loader, which just doesn't pass anything.
Cfr. commit
97b0511ce125b0cb95d73b198c1bdbb3cebc4de2("MIPS: TXx9:
Make firmware parameter passing more robust").
Thinking about this more, on platforms for which we do not have control about the bootloader, we can usually still get it to boot a wrapper. Such a wrapper could do the following:
- embedd the kernel
- embedd the appropriate dtb
- copy the relevant a0-a3 values and pass to the kernel a pointer to the valid dtb in the aX register
such a wrapper already exists, which is the code responsible for decompressing the kernel in arch/mips/boot/compressed.
If we want to support multiple flavors of the same SoC, using the same kernel image, we only need to relink the boot wrapper with the correct dtb (and kernel of course).
--
Florian
Quoted 35 lines · Florian Fainelli
Quoted 19 lines · On Wednesday 08 June 2011 09:15:14 Geert Uytterhoeven wrote:
Quoted 10 lines · David VomLehn
I took a look at the issue of passing device trees to the kernel and started by surveying the methods currently in use for passing information from the bootloader to the kernel. I came up with the ten approaches:
How MIPS Bootloaders Pass Information to the Kernel
---------------------------------------------------
Apologies for any errors; this was meant more to be a quick survey rather than a detailed analysis.Quoted 7 lines
6. a0 - argc
a1 - argv
a2 - non-standard envp
Command line created by concatenating argv strings, starting at argv[1]. The envp is a pointer to a list of char ptr to name/char ptr pairs.
Platforms: txx9Quoted 5 lines
This depends on the actual boot loader. My rbtx4927 has a VxWorks boot loader, which just doesn't pass anything.
Cfr. commit
97b0511ce125b0cb95d73b198c1bdbb3cebc4de2("MIPS: TXx9:
Make firmware parameter passing more robust").Thinking about this more, on platforms for which we do not have control about the bootloader, we can usually still get it to boot a wrapper. Such a wrapper could do the following:
- embedd the kernel
- embedd the appropriate dtb
- copy the relevant a0-a3 values and pass to the kernel a pointer to the valid dtb in the aX register
Quoted 6 lines
such a wrapper already exists, which is the code responsible for decompressing the kernel in
arch/mips/boot/compressed.If we want to support multiple flavors of the same SoC, using the same kernel image, we only need to relink the boot wrapper with the correct dtb (and kernel of course).
I'm definitely in favour of this approach (passing the dtb via a register) instead of passing it via the command line or something similar.
What strikes me about this debate (aside from the fact that it is the same debate we had on other architectures when DT was adopted) is that it seems to be focused on "here are all the different things all the MIPS platforms are doing now, so how can each of them be modified to graft in DT support". However, switching to DT is absolutely a new boot interface, regardless of how you cut it (or how the dtb address gets passed). Since this is something new, I *strongly* recommend using the opportunity to standardize on a single boot interface when passing a DT, and it does *not* have to be the same as any of the existing interfaces. By having only a single interface into the kernel, it eliminates any questions about which data the kernel should use as authoritative (which data takes precidence, legacy or DT), and you can get away from per-platform interface quirrks. Firmware needs to be modified regardless to take advantage full advantage of DT, so you may as well make them all change to use the same thing.
For firmware that does not, or can not be modified (like deployed firmware), the zImage wrapper is the ideal place to translate old firmware data into a DT representation.
On ARM, the kernel can be passed either an ATAGs list (legacy interface), or a DTB, and because of the signature on the data structures it can detect which interface it should be using. On PowerPC, we straight out dropped all the old boot interfaces from the kernel proper, and we use the zImage wrapper to inject data from old firmware interfaces into the DT at boot time (linked into the wrapper)
g.