[U-Boot-Users] U-Boot for AT91RM9200DK

Hi Rick et al.,
as I mentioned before U-Boot is running on our AT91RM9200 based board. I went down the path ATMEL was suggesting. They use this memory map on their eval board AT91RM9200DK:
24k Boot Image 32KB free 8KB Environment 64KB gzipped U-Boot image
The "Boot image" is a small (11k) piece of code which initialises clocks, flash, SDRAM and serial port. Then it decompresses the "gzipped U-Boot image" into SDRAM and jumps to it. The reason for that seems to be:
We chose, to put a compressed boot due to memory mapping constraints. We need to keep a sector for environment variables the 8Kbyte-size sector is enough.
They probably overlooked that you could embedded the environment into U-Boot. By using a correct u-boot.lds linker file one can reserve an 8Kbyte-size sector in the middle of U-Boot. So instead one could use this memory map:
56KB U-Boot 8KB Environment 64KB U-Boot
using the same 128KB of flash.
Since the CPU was setup by the bootloader there's no init and relocation code for the AT91RM9200 in U-Boot (yet).
So I spend a day, "wrote" some init and relocation code and now U-Boot is starting directly from flash and relocates itself to RAM. No Preboot needed. Nor gzipped image of U-Boot.
I would like to change the official U-Boot code for the AT91RM9200 and AT91RM9200DK so that it can be used without the need of another bootloader. This way it would be a lot easier for people to port U-Boot to their hardware.
What do you think? Anyone interessted?
I'd love to hear suggestion, where to put specific parts of the init code. Other ARM cpus use a board specific memsetup.S file. For an AT91RM9200 we have to setup more than just the SDRAM. Should we put all the init code into cpu/at91rm9200/{start.S} and use CONFIG_ and CFG_? Or should every AT91 based board copy the same code again and again into thier own subdirectory?
Looking forward to your ideas!
Thanks. And sorry for the long mail!

Hi Steven,
It's totally okay with me.
Should we put all the init code into cpu/at91rm9200/{start.S} and use CONFIG_ and CFG_?
I'd put it all in start.S and not define any CONFIG for it. But one thing you might check is if it will start up when the clocks are already configured. In other words, make sure your new u-boot can be started from an already running u-boot. This is necessary because the AT91RM9200 can be started from SPI DataFlash (or EEPROM) which requires a preloader. The preloader sets up clocks for SDRAM, etc and then launches u-boot.
I have a sperate entry in a Makefile for compiling u-boot up to run in ram so that I can fire a new u-boot while inside u-boot:
ram: cd u-boot-0.4.0; \ echo TEXT_BASE = 0x21fa0000 > board/at91rm9200dk/config.mk; \ make at91rm9200dk_config; \ make; \ cp -f u-boot.bin /tftpboot
And then from u-boot I do:
tftp 21fa0000 u-boot.bin # load u-boot go 21fa0000 # run u-boot
Or should every AT91 based board copy the same code again and again into thier own subdirectory?
I'd make it (optimistically) so they didn't have to copy.
Thanks for your work!
Rick
Hi Rick et al.,
as I mentioned before U-Boot is running on our AT91RM9200 based board. I went down the path ATMEL was suggesting. They use this memory map on their eval board AT91RM9200DK:
24k Boot Image 32KB free 8KB Environment 64KB gzipped U-Boot image
The "Boot image" is a small (11k) piece of code which initialises clocks, flash, SDRAM and serial port. Then it decompresses the "gzipped U-Boot image" into SDRAM and jumps to it. The reason for that seems to be:
We chose, to put a compressed boot due to memory mapping constraints. We need to keep a sector for environment variables the 8Kbyte-size sector is enough.
They probably overlooked that you could embedded the environment into U-Boot. By using a correct u-boot.lds linker file one can reserve an 8Kbyte-size sector in the middle of U-Boot. So instead one could use this memory map:
56KB U-Boot 8KB Environment 64KB U-Boot
using the same 128KB of flash.
Since the CPU was setup by the bootloader there's no init and relocation code for the AT91RM9200 in U-Boot (yet).
So I spend a day, "wrote" some init and relocation code and now U-Boot is starting directly from flash and relocates itself to RAM. No Preboot needed. Nor gzipped image of U-Boot.
I would like to change the official U-Boot code for the AT91RM9200 and AT91RM9200DK so that it can be used without the need of another bootloader. This way it would be a lot easier for people to port U-Boot to their hardware.
What do you think? Anyone interessted?
I'd love to hear suggestion, where to put specific parts of the init code. Other ARM cpus use a board specific memsetup.S file. For an AT91RM9200 we have to setup more than just the SDRAM. Should we put all the init code into cpu/at91rm9200/{start.S} and use CONFIG_ and CFG_? Or should every AT91 based board copy the same code again and again into thier own subdirectory?
Looking forward to your ideas!
Thanks. And sorry for the long mail!
-- Steven Scholz
imc Measurement & Control imc Meßsysteme GmbH Voltastr. 5 Voltastr. 5 13355 Berlin 13355 Berlin Germany Deutschland fon: +49 30 467090-0 Tel: 030 / 467090-0 fax: +49 30 4631576 fax: 030 / 4631576

Hi Rick,
Should we put all the init code into cpu/at91rm9200/{start.S} and use CONFIG_ and CFG_?
I'd put it all in start.S and not define any CONFIG for it.
Hmm. But my boards has a completly different clocking scheme! For instance: I use an 16MHz external clock oszillator. The eval board has an 18,xxx MHz crystal... So we need at least some CFG_'s for clock configuration.
Ok?

Hi Rick,
Should we put all the init code into cpu/at91rm9200/{start.S} and use CONFIG_ and CFG_?
I'd put it all in start.S and not define any CONFIG for it.
Hmm. But my boards has a completly different clocking scheme! For instance: I use an 16MHz external clock oszillator. The eval board has an 18,xxx MHz crystal... So we need at least some CFG_'s for clock configuration.
Ok?
No.
I have completely different crystals than the AT91RM9200DK. Do you want me to put my clock settings in u-boot? How about the 500 different AT91RM9200 boards that get designed this year? Do you want their specific stuff in u-boot?
By necessity u-boot is already nearing #ifdef hell because it supports so many devel boards (which is good). If we all threw our specific board design stuff in there, I don't think anyone in their right mind would use u-boot.
Just my opinion ;-) Maybe Wolfgang disagrees.
Rick
-- Steven Scholz
imc Measurement & Control imc Meßsysteme GmbH Voltastr. 5 Voltastr. 5 13355 Berlin 13355 Berlin Germany Deutschland fon: +49 30 467090-0 Tel: 030 / 467090-0 fax: +49 30 4631576 fax: 030 / 4631576

Rick,
Should we put all the init code into cpu/at91rm9200/{start.S} and use CONFIG_ and CFG_?
I'd put it all in start.S and not define any CONFIG for it.
Hmm. But my boards has a completly different clocking scheme! For instance: I use an 16MHz external clock oszillator. The eval board has an 18,xxx MHz crystal... So we need at least some CFG_'s for clock configuration.
I have completely different crystals than the AT91RM9200DK. Do you want me to put my clock settings in u-boot? How about the 500 different AT91RM9200 boards that get designed this year? Do you want their specific stuff in u-boot?
By necessity u-boot is already nearing #ifdef hell because it supports so many devel boards (which is good). If we all threw our specific board design stuff in there, I don't think anyone in their right mind would use u-boot.
Probably a misunderstanding!
How I am supposed to setup clocks and PLLs and serial port in the AT91RM9200 if I don't have any informations?
I thought of something like this in start.S:
#ifdef CFG_USE_EXT_CRYSTAL enable_main_oscillator; #endif
/* set up PLL */ set PLLA to CFG_PLLAR set PLLB to CFG_PLLBR ...
And the user just has to define CFG_USE_EXT_CRYSTAL, CFG_PLLAR etc in his board specific header file. Of course without the need to submit his configuration to the U-Boot CVS.
Ok?
Steven

Steven,
Isn't it true that the only reason you'd have this:
#ifdef CFG_USE_EXT_CRYSTAL
is so that you could configure non AT91RM9200DK hardware? (Since the AT91RM9200DK uses a crystal) If the answer is yes than I would say it doesn't belong in u-boot. If there were a switch on the AT91RM9200DK board that allowed different clock freq's then I would agree.
Rick

In message E1AD43F-0000xt-00@c-67-164-61-95.client.comcast.net you wrote:
Isn't it true that the only reason you'd have this:
#ifdef CFG_USE_EXT_CRYSTAL
is so that you could configure non AT91RM9200DK hardware? (Since the
Yes, probably (or can I use an external clock source on the AT91RM9200DK board).
AT91RM9200DK uses a crystal) If the answer is yes than I would say it doesn't belong in u-boot. If there were a switch on the AT91RM9200DK
You are wrong. We are talking about CPU dependend code. If this does not allow easy (non-#ifdef'ed) adaption to different boards the code is broken and needs fixing.
board that allowed different clock freq's then I would agree.
The AT91RM9200DK is just one out of many boards, right? Please do not insist on your implementation if your board specific code is in CPU common files.
There is a simple rule: CPU specific code shall go into CPU directo- ries, board specific stuff shall go into board directories.
If the clock intialization is board dependend (as it looks to me) that it does not belong into the CPU directory.
Best regards,
Wolfgang Denk

Dear Steven,
in message 3F993A32.80709@imc-berlin.de you wrote:
By necessity u-boot is already nearing #ifdef hell because it supports so many devel boards (which is good). If we all threw our specific board design stuff in there, I don't think anyone in their right mind would use u-boot.
Probably a misunderstanding!
Yes, on Rick's side.
How I am supposed to setup clocks and PLLs and serial port in the AT91RM9200 if I don't have any informations?
I thought of something like this in start.S:
#ifdef CFG_USE_EXT_CRYSTAL enable_main_oscillator; #endif
/* set up PLL */ set PLLA to CFG_PLLAR set PLLB to CFG_PLLBR ...
Looks clean to me. Probably even better would be to call "init_clocks" (or a function with a similar name) in start.S for _all_ boards, including the "at91rm9200dk".
Just for the record: the "at91rm9200dk" ist just one out of many boards. It is in no way better than any other board. "at91rm9200dk" dependend code shall be removed from the files in the cpu/at91rm9200 directory.
And the user just has to define CFG_USE_EXT_CRYSTAL, CFG_PLLAR etc in his board specific header file. Of course without the need to submit his configuration to the U-Boot CVS.
I don't understand this last sentence.
Either you are maintaining his own private version of U-Boot (in which case we don't care, and you don't need to ask for help on this mailing list which is dedicated to the _public_ source tree only), or you are working with the public version of U-Boot, in which case your board configuration obviously resides in the U-Boot CVS tree.
Best regards,
Wolfgang Denk

Dear Wolfgang,
I thought of something like this in start.S:
#ifdef CFG_USE_EXT_CRYSTAL enable_main_oscillator; #endif
/* set up PLL */ set PLLA to CFG_PLLAR set PLLB to CFG_PLLBR ...
Looks clean to me. Probably even better would be to call "init_clocks" (or a function with a similar name) in start.S for _all_ boards, including the "at91rm9200dk".
??? Should the function init_clocks() be in start.S or in board specific files? As it is done with memsetup() or platform() in other ARM implementations? Or should we write cpu_init(), board_init() etc. like in the PPC code?
Just for the record: the "at91rm9200dk" ist just one out of many boards. It is in no way better than any other board. "at91rm9200dk" dependend code shall be removed from the files in the cpu/at91rm9200 directory.
It's better in that everybody could buy such a board and run U-Boot on it. :o)
And the user just has to define CFG_USE_EXT_CRYSTAL, CFG_PLLAR etc in his board specific header file. Of course without the need to submit his configuration to the U-Boot CVS.
I don't understand this last sentence.
Either you are maintaining his own private version of U-Boot (in which case we don't care, and you don't need to ask for help on this mailing list which is dedicated to the _public_ source tree only), or you are working with the public version of U-Boot, in which case your board configuration obviously resides in the U-Boot CVS tree.
IMHO:
U-Boot code should be written in a way to make it very easy to port it to new, custom hardware without making (too many) changes on the generic and common code (as for instance the stuff inc cpu/at91rm92000/ directory).
In the best case just creating a new board include file with the appropriate definitions (like #undef CFG_USE_EXT_CRYSTAL; #define CFG_PLLA 0x12345678 etc.) should be enough to bring U-Boot up.
So if we write the code in cpu/at91rm92000/ generic enough then porting U-Boot to a new board is (at a first step) merely writing an new yourboard.h. Now if that's all I did I see no need to "bloat u-boot with unnecessary code". (Of course the CFG_ and CONFIG_ stuff must be documented e.g. in doc/README.AT91RM9200).
That's what I meant. Do we realy need thousends of yourboard.h just containing different values for CFG_PLLAR? I think we need them for "standard" eval boards. And for boards with some special feature. So I put my efford to provide generic code that could be used by others. That's why I rewrote my FPGA loading code, submitted a patch although my old board specific code was working good. And I will provide the code for our board in a while when I think it shows others how to use this code.
Argh... You know what I meant? I am not sure if I could make myself understood.

Hi,
in message 3F9BA845.8050505@imc-berlin.de you wrote:
Looks clean to me. Probably even better would be to call "init_clocks" (or a function with a similar name) in start.S for _all_ boards, including the "at91rm9200dk".
??? Should the function init_clocks() be in start.S or in board specific files?
I understood your argumentation such as if init_clocks() requires board dependend code. If this is the case, it belongs into a board specific file. If it is the same for (nearly) all at91rm9200 boards everything can stay as it is now.
As it is done with memsetup() or platform() in other ARM implementations? Or should we write cpu_init(), board_init() etc. like in the PPC code?
Well, I certainly like the idea of clearly splitting this stuff up as it was done on PowerPC. I do NOT intend to say that the PPC code was perfect.
Either you are maintaining his own private version of U-Boot (in which case we don't care, and you don't need to ask for help on this mailing list which is dedicated to the _public_ source tree only), or you are working with the public version of U-Boot, in which case your board configuration obviously resides in the U-Boot CVS tree.
IMHO:
U-Boot code should be written in a way to make it very easy to port it to new, custom hardware without making (too many) changes on the generic and common code (as for instance the stuff inc cpu/at91rm92000/ directory).
Agreeed.
In the best case just creating a new board include file with the appropriate definitions (like #undef CFG_USE_EXT_CRYSTAL; #define CFG_PLLA 0x12345678 etc.) should be enough to bring U-Boot up.
This will never work. There will always be board dependend stuff, and you will have to select a specific board config name. I don;t expect that there will ever be some common board specific code which will work for many boards from different vendors. There are too many things that can be implemented differently in hardware: RAM and Flash size, chip types, and bus widths; network interface, RTC, EEPROM, ...
So if we write the code in cpu/at91rm92000/ generic enough then porting U-Boot to a new board is (at a first step) merely writing an new yourboard.h.
I don't think this would ever work...
That's what I meant. Do we realy need thousends of yourboard.h just containing different values for CFG_PLLAR? I think we need them for "standard" eval boards.
The board config files contain many more things. Simple stuff like console port and baudrate, but also hardware dependend stuff like memory map, chip types and bus width, etc.
So I put my efford to provide generic code that could be used by others. That's
The intention is good, and we agree on that. But don't let it carry you too far. Be realistic.
Argh... You know what I meant? I am not sure if I could make myself understood.
I think I understand what you mean, but I don't expect that we can get rid of board dependend code completely. Nor do I see the need for that.
Best regards,
Wolfgang Denk

Dear Rick,
in message E1AD2xl-0000h1-00@c-67-164-61-95.client.comcast.net you wrote:
I have completely different crystals than the AT91RM9200DK. Do you want me to put my clock settings in u-boot? How about the 500
Yes, of course. If your board is supported by U-Boot you have to put your clock configuration somewhere in the U-Boot code. Best idea seems to be the board directory.
different AT91RM9200 boards that get designed this year? Do you want their specific stuff in u-boot?
Yes, of course. What else? If they are supported by U-Boot you have to put their clock configuration somewhere in the U-Boot code. Best idea seems to be the board directory.
By necessity u-boot is already nearing #ifdef hell because it supports so many devel boards (which is good). If we all threw
There is no real need for an #ifdef hell. I agree that we have already more than enough #ifdef's, but every now and then some parts get cleaned up. And you can make a good contribution by avoiding the necessity of new #ifdefs by helping to implement a clean separation of CPU and board dependend code.
our specific board design stuff in there, I don't think anyone in their right mind would use u-boot.
If you don't throw in your board specific stuff your board is not supported by the public version of U-Boot. Which means you will have to maintain your own version, and to make sure to publish your "private" version according to the GPL.
Just my opinion ;-) Maybe Wolfgang disagrees.
As you can see, I do.
Best regards,
Wolfgang Denk

Rick,
Should we put all the init code into cpu/at91rm9200/{start.S} and use CONFIG_ and CFG_?
I'd put it all in start.S and not define any CONFIG for it. But one thing you might check is if it will start up when the clocks are already configured. In other words, make sure your new u-boot can be started from an already running u-boot. This is necessary because the AT91RM9200 can be started from SPI DataFlash (or EEPROM) which requires a preloader. The preloader sets up clocks for SDRAM, etc and then launches u-boot.
I have a sperate entry in a Makefile for compiling u-boot up to run in ram so that I can fire a new u-boot while inside u-boot:
ram: cd u-boot-0.4.0; \ echo TEXT_BASE = 0x21fa0000 > board/at91rm9200dk/config.mk; \ make at91rm9200dk_config; \ make; \ cp -f u-boot.bin /tftpboot
And then from u-boot I do:
tftp 21fa0000 u-boot.bin # load u-boot go 21fa0000 # run u-boot
Ok. I see. So you're building a special version of U-Boot for this anyway (using make ram). Right?
I've seen: /* * we do sys-critical inits only at reboot, * not when booting from ram! */ #ifdef CONFIG_INIT_CRITICAL bl cpu_init_crit #endif
in cpu/arm920t/start.S and
#define CONFIG_INIT_CRITICAL /* undef for developing */
in some board specific header file.
So. Would you agree on a mechanism like that?
You could still do something like that in your Makefile:
ram: cd u-boot-0.4.0; \ echo TEXT_BASE = 0x21fa0000 > board/at91rm9200dk/config.mk; \ make at91rm9200dk_config; \
echo "#undef CONFIG_INIT_CRITICAL" >> include/config.h; \
make; \ cp -f u-boot.bin /tftpboot
I think this would better better than trying to autodetect if the system was already configured. Ok?
Steven

Dear Steven, Rick,
in message 3F9CC600.2080209@imc-berlin.de you wrote:
I have a sperate entry in a Makefile for compiling u-boot up to run in ram so that I can fire a new u-boot while inside u-boot:
ram: cd u-boot-0.4.0; \ echo TEXT_BASE = 0x21fa0000 > board/at91rm9200dk/config.mk; \
...
You could still do something like that in your Makefile:
ram: cd u-boot-0.4.0; \ echo TEXT_BASE = 0x21fa0000 > board/at91rm9200dk/config.mk; \
STOP! NO!!
Please never ever modify any source files in the Make script!!!
Best regards,
Wolfgang Denk

Dear Wolfgang , Rick,
I have a sperate entry in a Makefile for compiling u-boot up to run in ram so that I can fire a new u-boot while inside u-boot:
ram: cd u-boot-0.4.0; \ echo TEXT_BASE = 0x21fa0000 > board/at91rm9200dk/config.mk; \
...
You could still do something like that in your Makefile:
ram: cd u-boot-0.4.0; \ echo TEXT_BASE = 0x21fa0000 > board/at91rm9200dk/config.mk; \
STOP! NO!!
Please never ever modify any source files in the Make script!!!
:o)
Ok. Ok. Maybe the better way would be:
RICKs_RAM_config: unconfig @./mkconfig $(@:_config=) arm at91rm9200 RICKSBOARDS @echo '#define TEXT_BASE 0xFOOBAR' >>include/config.h; @echo '#undef CONFIG_INIT_CRITICAL' >>include/config.h;
and then
ifndef TEXT_BASE TEXT_BASE = 0xBLABLUB endif
in board/at91rm9200dk/config.mk.
Ok?
Steven

In message 3F9CD66E.8040701@imc-berlin.de you wrote:
Ok. Ok. Maybe the better way would be:
RICKs_RAM_config: unconfig @./mkconfig $(@:_config=) arm at91rm9200 RICKSBOARDS @echo '#define TEXT_BASE 0xFOOBAR' >>include/config.h; @echo '#undef CONFIG_INIT_CRITICAL' >>include/config.h;
and then
ifndef TEXT_BASE TEXT_BASE = 0xBLABLUB endif
in board/at91rm9200dk/config.mk.
Ok?
No, this will not work, as include/config.h is a C heaer file following C preprocessor syntax, while board/at91rm9200dk/config.mk is included by a Makefile and thus follows Makefile syntax.
Best regards,
Wolfgang Denk

Wolfgang,
ifndef TEXT_BASE TEXT_BASE = 0xBLABLUB endif
in board/at91rm9200dk/config.mk.
Ok?
No, this will not work, as include/config.h is a C heaer file following C preprocessor syntax, while board/at91rm9200dk/config.mk is included by a Makefile and thus follows Makefile syntax.
Hmm. board/trab/config.mk contains such lines. If it does not work anyway the maintainer should remove it as not to send other down the wrong path! ;-)
Or is the trick done by the line
sinclude $(TOPDIR)/board/$(BOARDDIR)/config.tmp
???
Steven

Dear Steven,
in message 3F9D0045.3040106@imc-berlin.de you wrote:
No, this will not work, as include/config.h is a C heaer file following C preprocessor syntax, while board/at91rm9200dk/config.mk is included by a Makefile and thus follows Makefile syntax.
Hmm. board/trab/config.mk contains such lines.
board/trab/config.mk does NOT include the noard config file (which in this case would be include/configs/trab.h).
If it does not work anyway the maintainer should remove it as not to send other down the wrong path! ;-)
board/trab/config.mk does work.
Or is the trick done by the line
sinclude $(TOPDIR)/board/$(BOARDDIR)/config.tmp
This is no trick at all. It's just one of the possible ways to pass config options into config.mk
Best regards,
Wolfgang Denk

Dear Wolfgang,
board/trab/config.mk does NOT include the noard config file (which in this case would be include/configs/trab.h).
... sinclude $(TOPDIR)/board/$(BOARDDIR)/config.tmp
This is no trick at all. It's just one of the possible ways to pass config options into config.mk
Ah. Ok I see now.
Thanks,
Steven

Steven & Wolfgang,
tftp 21fa0000 u-boot.bin # load u-boot go 21fa0000 # run u-boot
Ok. I see. So you're building a special version of U-Boot for this anyway (using make ram). Right?
Yes.
STOP! NO!!
Please never ever modify any source files in the Make script!!!
Don't worry, it's in a Makefile that not in the u-boot tree. And I promise not to send a patch ;-)
Rick

Dear Rick,
in message E1AE9RV-0000fx-00@amazonia.efn.org you wrote:
Please never ever modify any source files in the Make script!!!
Don't worry, it's in a Makefile that not in the u-boot tree. And I promise not to send a patch ;-)
I would never accept it. I consider it a VERY BAD idea to have a Makefile modyfying files which are under source control (CVS).
Best regards,
Wolfgang Denk

Hi,
in message 3F98EA80.9040302@imc-berlin.de you wrote:
So I spend a day, "wrote" some init and relocation code and now U-Boot is starting directly from flash and relocates itself to RAM. No Preboot need ed. Nor gzipped image of U-Boot.
Thanks. I really appreciate this effort, especially since it allows to run a "pure" U-Boot on this architecture.
I would like to change the official U-Boot code for the AT91RM9200 and AT91RM9200DK so that it can be used without the need of another bootloader.
I''d appreciate such an effort.
Just for my understanding: the AT91RM9200DK is just one specific board usingt he AT91RM9200 (AT91RM9200DK == AT91RM9200 "D"evelopment "K"it?).
What do you think? Anyone interessted?
Yes, me :-)
I'd love to hear suggestion, where to put specific parts of the init code. Other ARM cpus use a board specific memsetup.S file. For an AT91RM9200 we have to setup more than just the SDRAM. Should we put all the init code into cpu/at91rm9200/{start.S} and use CON FIG_ and CFG_?
In cases where board-specific code is required the common code (like cpu/at91rm9200/start.S) should call board-specific init functions which will have to be implemented by code in the board dependend directories.
Or should every AT91 based board copy the same code again and again into thier own subdirectory?
NO !!!!
Best regards,
Wolfgang Denk
participants (3)
-
Rick Bronson
-
Steven Scholz
-
Wolfgang Denk