Saturday, November 7, 2009

Recent happening - PXA3xx, u-boot etc.

I just want to write some sum of what happened since last time I posted something here as stuff actually pretty piled up and I'm overly busy now. Expect somehow longer entry as quite a bit happened actually.

All this machinery started back in late September, when I got a Toradex Colibri carrier board with a PXA320 CPU card from INCOME s.r.o. and was instructed to prepare a decent bootloader for it and possibly make Linux kernel run smoothly on it. Sure, sounds easy, it's a Marvell CPU afterall and U-Boot already has some support for a few boards with PXA3xx too. Moreover, it's not too different from PXA2xx series, right? Yes sure, it's not, but there are a few changes.

I was suffering for some time, trying to make use of the preinstalled EBOOT bootloader to load Linux and even wrote some wrapper so it loads the kernel correctly at least, but I gave up on this idea as it turned out EBOOT is a worthless piece of crap. Not to mention, EBOOT is a proprietary goo. So I figured I need to replace it. U-Boot was the only choice here of course, but here came the first difference between PXA2xx and PXA3xx. The PXA3xx CPU does not need a NOR flash to boot from, it can boot directly from the NAND flash. Actually, there is something called BootROM buried in the CPU as I figured out later, but it's not possible to read it's contents without electron microscopy I think. Well this BootROM apparently configures the NAND properly, copies it's first sector to SRAM and executes it. But here popped in another problem, I managed to overwrite the first sector with not working code rendering the board unusable. Sadly, there is no utility for Linux that can flash the PXA3xx board so I had to use their proprietary one to reflash the board.

After numerous reflashes and testing, digging through the bootloader images Toradex released publicly and analyzing them, I managed to put together an open source GPLed IPL (initial program loader) that can be stored in the first sector of NAND with a sole purpose of loading further sectors from NAND, copying them to SRAM and then jumping to the beginning of these copied data. For this IPL, I established the OpenPXA project hosted on SourceForge as the plan is to extend it's support to other boards as you'll figure out later. Well, the data I mentioned a while ago that are being copied and executed are actually U-Boot. Maybe you are asking -- why is it so complicated. That's because the BootROM can apparently load only the first sector from NAND, the rest has to be done by the IPL, that's how the chip is.

Back to the U-Boot. There was one more obstacle I had to fight, it was the RAM. The PXA3xx supports DDR DRAM besides some other types of DRAM and the hardware I have has the DDR DRAM. That's why I had to write the initialization routine, which soon turned out to be one hell of a hard work to be done properly. As a side story, I made a decision to stick most of the hardware initialization into the U-Boot and keep the IPL size to the minimum. That's also why the IPL is loading the U-Boot into SRAM, to avoid initializing the DRAM controller.

After all this suffering, the current status of U-Boot for the Colibri/PXA320 is such that it's usable to boot Linux from MMC or NAND, the CPU is properly configured, DRAM works just fine. There are still a few problems though. The most noticable one is that the NAND can't be written from U-Boot, but I suspect that's because of a GCC bug that produces wrong code causing the U-Boot to hang. The other problem is that the ethernet adapter doesn't work in U-Boot, but that's being worked on now. It actually works from Linux so that's not much of a problem. Just as a side note, I sometimes update the patches for U-Boot in the OpenPXA git so if you are interested, you can find them there.

Mentioning GCC bugs, let me warn you that you should not even try compiling U-Boot with >= GCC4.3. It produces weird code and makes the U-Boot not work properly, like unexpectedly hang and such. I tried fixing some of those issues in U-Boot, but there are still many so stick with GCC4.2 for the time being. The exceptionally nasty one was with 64bit division. In the end, I ripped the code for 64bit division from Linux kernel and stick it into U-Boot, but that's more like a workaround.

Before I disclose my future plans with U-Boot on PXA3xx, I first need to explain why I'm so into it probably. That's because somewhere along the process of fixing U-Boot, I made some negotiations with a certain corporation that makes CPUs and such (I'm not sure if I can disclose anything more here, sorry) and was supplied some hardware to hack on. So that's why I'm sticking very closely to this and why I'm investing such a load of my time to this low-level stuff. Also I have to say, the people I communicated with so far are awesome and I like it the way it is.

So to the plans I have with the IPL and U-Boot. Firstly, I'll have to hack on the IPL a bit to make it support PXA310, Monahans LV CPU. Then there was an idea to use the values from BootROM to auto-configure the NAND in the IPL and possibly even later in U-Boot and Linux, which is awesome as the NAND will be technically auto-detected and we won't have to care for it much. Next of course will be fixing of the ethernet on the Colibri/PXA320, ok, maybe this will be first as I'm getting close here. What I'd also like to have working is the USB host in U-Boot so the thing can also boot from an USB thumb-drive or something.

Besides these plans with IPL and U-Boot, I have an idea that there needs to be an improvement made in the Linux kernel concerning the UCB1400 chip driver which is integrated on the Colibri/PXA320 module. This improvement would make use of the recently merged possibility of passing platform data through the AC97 bus. Let me explain properly. I recently got an email from someone that the pseudo-auto-detection routine which somehow should detect the proper touchscreen IRQ GPIO for UCB1400 doesn't work on his hardware. Well that sucks and it was unavoidable anyway I think. So this patch would pertain to removal of this routine altogether and modifying all the platforms that use the UCB1400 driver to supply the touchscreen IRQ GPIO as AC97 bus platform data. There are just two or three such platforms so it's not much of a problem anyway.

Well this is about it, life was pretty busy recently and the article actually grew quite long, sorry to hold you here for so long. I hope you enjoyed your stay at least.

No comments: