The folder have "sd.S", "shell.c" and "shell_funcs.c" files, which are
from Chumby sources:
http://files.chumby.com/source/falconwing/build2370/bootstream-1.0.tgz
I think "bootstream-1.0.tgz" is a bootloader for Chumby version which
uses imx233. Bob told me that version do use a uSDCard for code and so
I believe we can try re-use that code, should be the same thing we
need, a first bootloader that uses no more than 16kbytes.
There are calls to init and read from SDCard, but they seems to be to
some undocumented address!!! seems voodoo :-)
I am still try to figure/understand/learn a way to have a MBR+FAT32
with music/data files and imx233 1st and 2nd (rockbox) bootloader...
--
Cumprimentos,
Jorge Pinto
I don't know. I am sending this e-mail to Bunnie and Sean Cross, they
can say for sure where they found that addresses and way to init and
read uSDCard using ROM address calls.
Bunnie, Sean Cross, can you please help us and tell how did you get
the information to use calls from ROM of imx233, to use the uSDCard?
(I mean, the code of "sd.S" file on
"http://files.chumby.com/source/falconwing/build2370/bootstream-1.0.tgz"??
If you don't remember, me and Bob, we are working on OpenSource
project Lyre, portable audio player for running the OpenSource Rockbox
firmware: http://lyre.sourceforge.net/
Thanks you.
Hello :-)
Thanks for sharing your code/work!
I am not sure we will use that code, but I guess we will since you
guys at Chumby did. Right now, I would like to know if is really a
need to use ROM calls... why don't do SDCard drivers? or is a
limitation on the 16kbytes space for first bootloader? if so, doesn't
FreeScale give a solution?
I am still trying to understand the "bootstream_make_bootable.pl"
file. I need to understand if I can (I would like to) use 1 uSDCard to
boot from and use for user data/music files. I am looking to use a
FAT32 partition.
I don't believe I will be able to improve that code you shared... I
barely can code... I think I am a kind of beginner/hacker... example
codes for me are very important. Seems to me that FreeScale don't give
good app notes/example codes, when comparing to Atmel or NXP (were I
have a bit more experience from using in the past).
Another thing: on Chumby wiki, I can't find any info about this. Seems
every one just boots Linux... the same on Lady Ada site Chumby Hacker
board: http://www.ladyada.net/learn/chumby/
Here's an updated sd.S and sd.h that handle all three die revs we've seen.
--
Cumprimentos,
Jorge Pinto
On 08-Jan-2011, at 8:57 AM, Casainho wrote:
> On Sat, Jan 8, 2011 at 4:08 PM, Sean Cross <se...@chumby.com> wrote:
>> We disassembled the rom to find the address. You're free to use that code.
>> I'd be curious to see if you could improve it in any way.
>
> Hello :-)
>
> Thanks for sharing your code/work!
>
> I am not sure we will use that code, but I guess we will since you
> guys at Chumby did. Right now, I would like to know if is really a
> need to use ROM calls... why don't do SDCard drivers? or is a
> limitation on the 16kbytes space for first bootloader? if so, doesn't
> FreeScale give a solution?
We decided to use the ROM calls based on the assumption that there's a
lot of variation in SD cards, and if our code was executing we're
guaranteed that those calls would be able to read from the card. If
we implemented our own driver, there was always a chance that we'd
introduce a timing bug. Also, I didn't really understand how DMA
worked at the time, and it was easier to just make the calls
ourselves.
Since you're porting your own OS, it may be preferable to just create
your own SB2 file using elftosb2. I believe they have an example of a
bootlet to load and jump to a Linux kernel. I'm not very familiar
with Rockbox, but SB2 makes it very easy to load a blob to a specific
location of memory and jump to it. We chose to implement our own
bootloader because we have a unique two-kernel recovery system that
the ROM loader didn't work with.
> I am still trying to understand the "bootstream_make_bootable.pl"
> file. I need to understand if I can (I would like to) use 1 uSDCard to
> boot from and use for user data/music files. I am looking to use a
> FAT32 partition.
Do your boards have the MBR fuse blown? If so, you just have to set
up your partition table so that one of the partitions has a signature
of 0x53, and then load the SB2 file at the beginning of that
partition. Then you won't need to use bootstream_make_bootable.pl.
This makes hacking easier, because you can simply dd one card onto
another and have it work without needing to "re-bless" the card by
updating the BCB, which is the structure at the end of the card that
instructs the ROM where to load the SB2 image from. The last sector
of an SD card varies widely even amongst cards that are the same size.
If you don't have the MBR fuse blown -- which is how they come from
the factory by default -- then bootstream_make_bootable.pl is useful
for doing debug, because it will scan the start of an SD card (up to
about 20 megabytes, IIRC) for the SB2 signature, and then write the
BCB at the end of the card.
One option may be to create a single partition on the card that is
FAT32, but make it about 20 megabytes smaller than the card's size.
Then you can use the attached write_bootstream script to write both an
SB2 and a correct BCB to the end of the card.
Let me know if you'd like more information on how to bootstrap an imx233.
> Another thing: on Chumby wiki, I can't find any info about this. Seems
> every one just boots Linux... the same on Lady Ada site Chumby Hacker
> board: http://www.ladyada.net/learn/chumby/
The hacker boards run software that is largely identical to the stock
chumby firmware. It simply has a check to read the board's version,
and makes adjustments like not starting up the flash player, or
setting output to the TV by default. In fact, you should be able to
take the SD card out of a hacker board and put it in a chumby One and
have it behave like a chumby One.
Sean
--
Cumprimentos,
Jorge Pinto
We disassembled the rom to find the address. You're free to use that
code. I'd be curious to see if you could improve it in any way.
I've got a newer version of that code that supports multiple versions
of the rom. I believe the version we shipped only supported the B rev,
and Freescale is up to C rev now. I'll get that to you when I'm by a
computer, and not on my phone.
On Jan 8, 2011 6:51 AM, "Casainho" <casa...@gmail.com> wrote:
--
Cumprimentos,
Jorge Pinto
On imx233 datasheet says that only 16K of OCRAM are free for loading
application data(1st bootloader). Do you know if ROM just reads the
first 16K from SDCard?
> Do your boards have the MBR fuse blown?
Yes I do.
If so, you just have to set up your partition table so that one of
the partitions has a signature of 0x53, and then load the SB2 file at
the beginning of that partition.
There is a document written by Bob (which I don't know have references
from some Chumby other documents) that says: "1. need partition of
type 'S' 0x53 with small size (e.g 64K)". Do you know if the partition
really need to be that small?
imx233 datasheet says: "The boot image address is stored at offset
0x08 of partition table and size of the image at offset 0x10 of
partition table." ---> it may have an error, because in partition
table, 0x0C have the size of partition and not 0x10. But my question
is, ROM code looks to the partition size or not? I guess not and just
load first 16K to OCRAM... what do you think?
My idea:
- have a 1st partition of for example 2Mbytes, signature 0x53;
- MBR will be on the first sector (512bytes each sector) and will
point the start of first partition at 2nd sector;
- the 1st 1Mbytes of the partition will be reserved for 1st booloader,
from which ROM should read only the first 16K to OCRAM;
- the 2nd 1MByte will hold the 2nd bootloader always starting at
sector 2049! So 1st bootloader will always find the 2nd bootloader on
sectors [2049-4097] of uSDCard.
- another partition of type FAT32 exist on uSDCard, just after the
sector 4097 (512bytes MBR + 1Mbyte 1st bootloader + 1Mbyte 2nd
bootloader) until the end.
Do you think this would work?
Ok, it's better. I assume each call runs the code previously loaded to
OCRAM, so, the limitation of 16K should be on this piece of code.
>> My idea:
>> - have a 1st partition of for example 2Mbytes, signature 0x53;
>> - MBR will be on the first sector (512bytes each sector) and will
>> point the start of first partition at 2nd sector;
>> - the 1st 1Mbytes of the partition will be reserved for 1st booloader,
>> from which ROM should read only the first 16K to OCRAM;
>> - the 2nd 1MByte will hold the 2nd bootloader always starting at
>> sector 2049! So 1st bootloader will always find the 2nd bootloader on
>> sectors [2049-4097] of uSDCard.
>>
>> - another partition of type FAT32 exist on uSDCard, just after the
>> sector 4097 (512bytes MBR + 1Mbyte 1st bootloader + 1Mbyte 2nd
>> bootloader) until the end.
>>
>> Do you think this would work?
>
> It could work. Though what is the purpose of the 1st / 2nd bootloader? If you want to load a kernel or config file of some sort off of the FAT partition, you can fit that all in the OCRAM. A small FAT driver combined with either an SD driver or calls to the ROM should do nicely.
Rockbox is Rockbox bootloader + Rockbox firmware. Bootloader loads the
firmware from a FAT partition (the same that stores user audio/data),
so, bootloader needs to configure imx233 clock + LCD + SDRAM + uSDCard
+ FAT drivers. I know (after looking at other Rockbox targets) that
16K is not enough.
But maybe I can do:
section (0) {
load power_prep;
call power_prep;
load clocks_prep;
call clocks_prep;
load sdram_prep;
call sdram_prep;
load rockbox_bootloader 0x40008000;
jump rockbox_bootloader;
}
I think that will work, no? If so, I just need to only a
file/bootstream an place it on the first partition :-)
Now I think it is easier then I was thinking before :-) Thanks ;-)
On 08-Jan-2011, at 4:03 PM, Casainho wrote:
>>> I am not sure we will use that code, but I guess we will since you
>>> guys at Chumby did. Right now, I would like to know if is really a
>>> need to use ROM calls... why don't do SDCard drivers? or is a
>>> limitation on the 16kbytes space for first bootloader? if so, doesn't
>>> FreeScale give a solution?
>>
>> We decided to use the ROM calls based on the assumption that there's a lot of variation in SD cards, and if our code was executing we're guaranteed that those calls would be able to read from the card. If we implemented our own driver, there was always a chance that we'd introduce a timing bug. Also, I didn't really understand how DMA worked at the time, and it was easier to just make the calls ourselves.
>
> On imx233 datasheet says that only 16K of OCRAM are free for loading
> application data(1st bootloader). Do you know if ROM just reads the
> first 16K from SDCard?
The ROM reads an SB2 file, which contains instructions on what code to
load where. As an example, it's possible to instruct the ROM to load
first some initial bootlets to configure external RAM, and then to
load a full Linux kernel to offset 0x40008000. The resulting SB2 file
is usually around 3 megs. An example of an elftosb2 config file that
does this is:
sources {
power_prep="images/power";
clocks_prep="images/clocks";
sdram_prep="images/sdram_prep";
linux_prep="images/linux_prep";
zImage="images/zImage";
}
section (0) {
load power_prep;
call power_prep;
load clocks_prep;
call clocks_prep;
load sdram_prep;
call sdram_prep;
load linux_prep;
call linux_prep;
load zImage > 0x40008000;
jump linux_prep;
}
> There is a document written by Bob (which I don't know have references
> from some Chumby other documents) that says: "1. need partition of
> type 'S' 0x53 with small size (e.g 64K)". Do you know if the partition
> really need to be that small?
This is not a requirement. As an example, the first partition on the
chumby is 16 megabytes.
> imx233 datasheet says: "The boot image address is stored at offset
> 0x08 of partition table and size of the image at offset 0x10 of
> partition table." ---> it may have an error, because in partition
> table, 0x0C have the size of partition and not 0x10. But my question
> is, ROM code looks to the partition size or not? I guess not and just
> load first 16K to OCRAM... what do you think?
ROM code only pays attention to the offset, and ignores the size parameter.
> My idea:
> - have a 1st partition of for example 2Mbytes, signature 0x53;
> - MBR will be on the first sector (512bytes each sector) and will
> point the start of first partition at 2nd sector;
> - the 1st 1Mbytes of the partition will be reserved for 1st booloader,
> from which ROM should read only the first 16K to OCRAM;
> - the 2nd 1MByte will hold the 2nd bootloader always starting at
> sector 2049! So 1st bootloader will always find the 2nd bootloader on
> sectors [2049-4097] of uSDCard.
>
> - another partition of type FAT32 exist on uSDCard, just after the
> sector 4097 (512bytes MBR + 1Mbyte 1st bootloader + 1Mbyte 2nd
> bootloader) until the end.
>
> Do you think this would work?
It could work. Though what is the purpose of the 1st / 2nd
bootloader? If you want to load a kernel or config file of some sort
off of the FAT partition, you can fit that all in the OCRAM. A small
FAT driver combined with either an SD driver or calls to the ROM
should do nicely.
Thank you for all. Me and Bob, we found on Linux tree the sources for
SDCard drivers, which is the only piece missing for our needs.
LCD, we are using one very cheap which is SPI. I don't have
money/business model and so we are going DIY (cheap, that we can easy
source and assembly). Even the enclosure, I am doing the design and
print 3D it :-) -- I am sending a picture of actual prototype.
The imx233 board is also OpenHardware, provided from Opendous:
http://code.google.com/p/propendous/
Later, if we need something, we will contact you again. We will also
link on our site to Chumby, since we are using a lot of work from your
project - and we are also OpenSource :-)
We are doing (parallel) JTAG debug using Eclipse, which is great. We
also already wrote the "power + clocks + our SDRAM + blink LED" code
on uSDCard and the imx233 booted is correctly :-)
I think we are now pretty ready to start working/focus only on Rockbox port :-)
I couldn't understand this question looking at Chumby sources.
My "entry.S" file do:
/* Enter the main() - it should never return */
bl main
Should I put that at end of assembly file and it will return the control to ROM?
I am sending the code so you can look if you want.
Ok, I see now that the "mov pc, lr" will working, as link register
should have the address the called _start on entry.S :-)
Thanks.
> The bootlets should already set up power, EMI, and clocks, so you shouldn't need to do that yourself. Are you not seeing that happening?
Well, I am using the sources (the file I sent before) I got (from
Chumby?? I am not sure now) and they are working. I prefer to continue
with that sources.
I will now build them and also build a blink LED code, which I will
put on bootstream on uSDCard... if LED will blink, then the 1st part
(of power + clock + SDRAM) are working. Later I just need to change
the LED blink code for the Rockbox bootloader :-)
Thanks.
--
Cumprimentos,
Jorge Pinto
Sure. And we have a working code already ;-)
I think I will make the blink LED code to run from SDRAM and use some
increment variables (also on SDRAM) to change the LED blink delay :-)
> The ROM reads an SB2 file, which contains instructions on what code to load where. As an example, it's possible to instruct the ROM to load first some initial bootlets to configure external RAM, and then to load a full Linux kernel to offset 0x40008000. The resulting SB2 file is usually around 3 megs. An example of an elftosb2 config file that does this is:
>
> sources {
> power_prep="images/power";
> clocks_prep="images/clocks";
> sdram_prep="images/sdram_prep";
> linux_prep="images/linux_prep";
> zImage="images/zImage";
> }
>
> section (0) {
>
> load power_prep;
> call power_prep;
>
> load clocks_prep;
> call clocks_prep;
>
> load sdram_prep;
> call sdram_prep;
>
> load linux_prep;
> call linux_prep;
>
> load zImage > 0x40008000;
> jump linux_prep;
> }
Right now I have this file:
sources
{
system_init = "output/system_init.elf";
rockbox_bootloader =
"../../../../../build-lyre_v2-bootloader/bootloader.elf";
}
section (0)
{
/* initialize power, clock and SDRAM */
load system_init;
call system_init;
/* load and run Rockbox bootloader */
load rockbox_bootloader > 0x41F00000;
jump rockbox_bootloader;
}
I get none error if I do: "load rockbox_bootloader > 0x41F00000;" but
that would load to OCRAM of imx233. I get this error trying to load to
SDRAM address 0x41F00000:
elftosb2/elftosb2 -V -z -c src/system_init_sb.db -o ./output/system_init.bin
error: constant targets only support single-segment sources
Do you know what that error means?
Good news! I got the help from Pamaury Rockbox hacker, to be able to
finally use elftosb2 ok.
This sb code file, initialize imx233 clocks @ 454MHz and external
SDRAM, and finally loads to SDRAM and run a blink LED code - this code
is the actual Rockbox bootloader. I need to test it, I will do it
tomorrow.
I all this works, it means there is more no need to develop a 1st
bootloader, something I think I would not be able to do.
I hope all this works and if so, next task is blink LED using Rockbox
kernel delay :-)
Here is the feedback from elftosb2 (cod is on SVN:
http://lyre.svn.sourceforge.net/viewvc/lyre/propendous-imx233_board/firmware/rockbox_svn/):
cas@cas-laptop:~/lyre_project/lyre_svn/propendous-imx233_board/firmware/rockbox_svn/firmware/target/arm/imx233/system_init$
make sb
elftosb2/elftosb2 -V -z -c src/system_init_sb.db \
-o ./output/system_init_sb.bin
Boot Section 0x00000000:
LOAD | addr=0x00000000 | len=0x00000038 | crc=0x868b79b1
LOAD | addr=0x00000040 | len=0x000011a8 | crc=0x269f7ccf
CALL | addr=0x00000000 | arg=0x00000000
LOAD | addr=0x41f00000 | len=0x00000088 | crc=0xf3f7fe3d
FILL | addr=0x41f00088 | len=0x00000800 | pattern=0x00000000
JUMP | addr=0x41f00000 | arg=0x00000000
On Sat, Jan 15, 2011 at 4:34 AM, Sean Cross <se...@chumby.com> wrote:
>>
>> Right now I have this file:
>>
>> sources
>> {
>> system_init = "output/system_init.elf";
>> rockbox_bootloader =
>> "../../../../../build-lyre_v2-bootloader/bootloader.elf";
>> }
>>
>> section (0)
>> {
>> /* initialize power, clock and SDRAM */
>> load system_init;
>> call system_init;
>>
>> /* load and run Rockbox bootloader */
>> load rockbox_bootloader > 0x41F00000;
>> jump rockbox_bootloader;
>> }
>>
>> I get none error if I do: "load rockbox_bootloader > 0x41F00000;" but
>> that would load to OCRAM of imx233. I get this error trying to load to
>> SDRAM address 0x41F00000:
>>
>> elftosb2/elftosb2 -V -z -c src/system_init_sb.db -o ./output/system_init.bin
>> error: constant targets only support single-segment sources
>>
>> Do you know what that error means?
>
> How are you compiling bootloader.elf? The chumby bootloader is built by running:
>
> $(LD) -o chumby_stub *.o -static -nostdlib -T chumby_stub.ld
>
> chumby_stub.ld is compiled by running:
>
> cpp -P -DBASE_ADDR=0x00002000 -o chumby_stub.ld chumby_stub.ld.in
>
> THe contents of chumby_stub.ld.in are:
>
> OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
> OUTPUT_ARCH(arm)
> ENTRY(_start)
>
> SECTIONS
> {
> /*
> * Locate the .start section at the origin. The boot ROM will be told to
> * jump to address zero, and that's where we want to put the first
> * instruction we execute.
> */
> . = BASE_ADDR;
> .start : { KEEP(*(.start)) }
>
> . = ALIGN(32);
> .text : { KEEP(*(.text)) }
>
> . = ALIGN(32);
> .rodata : { KEEP(*(.rodata)) }
>
> . = ALIGN(32);
> .cmdlines : { KEEP(*(.cmdlines)) }
>
> . = ALIGN(32);
> .data : { KEEP(*(.data)) }
>
> . = ALIGN(32);
> .got : { KEEP(*(.got)) }
>
> . = ALIGN(32);
> _end = .;
>
> . = ALIGN(32);
> _bss_start = .;
> .bss : { KEEP(*(.bss*)) }
> . = ALIGN(32);
> _bss_end = .;
>
> _heap_start = .;
> }
>
> Probably what's going on is that gcc is adding extra sections that elftosb2 doesn't recognize. You can probably fix that by just using objcopy, but compiling with your own map is the way Freescale does it, so it's the way chumby did it.
From last time, I got a help from a Rockbox dev (Amaury from France),
to get elftosb2 working. Doing this, it does not work:
/* load and run Rockbox bootloader */
load rockbox_bootloader > 0x41F00000;
jump rockbox_bootloader;
But this, it works!
/* load and run Rockbox bootloader */
load rockbox_bootloader;
jump rockbox_bootloader;
My current sb file is:
sources
{
system_init = "output/system_init.elf";
rockbox_bootloader =
"../../../../../build-lyre_v2-bootloader/bootloader.elf";
}
section (0)
{
/* initialize power, clock and SDRAM */
load system_init;
call system_init;
/* load and run Rockbox bootloader */
load rockbox_bootloader;
jump rockbox_bootloader;
}
and it works perfectly, if system_init + rockbox_bootloader are both
at ".text IRAMORIG :". I see the system_init initializing the clocks
and SDRAM, after it leaves to imx233 ROM which in turns loads
rockbox_bootloader again to the IRAMORIG and run it.
rockbox_bootloader is just a blink_led code.
But I need to have rockbox_bootloader running from SDRAM, and so if I
put it at: ".text (DRAMORIG + DRAMSIZE - 1M) : AT (DRAMORIG + DRAMSIZE
- 1M)"
the rockbox_bootloader simple doesn't run :-(
I can clearly see the system_init running at his end and, instead it
runs rockbox_bootloader, I see the like the board "rebooting", running
in a infinite loop the system_init...
Do you have any idea why is this happening?
Thank you.
Hello :-)
I got it ;-) but it was a luck...
I didn't what you suggested because I don't know how to "control" the
link command on Rockbox makefile... anyway, I tested a lot of changes
and I found this:
//.text DRAMORIG : AT (0) // NOT WORKING, board do a kind of reboot??
.text 0x4000000 : AT (0) // WORKS
//.text 0x41F00000 : AT (0) // NOT WORKING, board do a kind of reboot??
{
*(.glue_7)
*(.glue_7t)
(...)
First, DRAMORIG == 0x4000000, so I can't understand why first option
don't work... I tested it a few times to verify.
2nd option works, and 0x4000000 is the start of SDRAM.
3rd option don't work, which is 0x41F00000 == (DRAMORIG + DRAMSIZE -
1M), because I need to place Rockbox bootloader at a different place
in SDRAM from Rockbox firmware (which bootloader will load and jump to
at SDRAM begin).
Do you see any reason for it not work with 0x41F00000?
Thank you :-)
(I commited the code to SVN: http://lyre.svn.sourceforge.net/viewvc/lyre/)
> Try linking your rockbox_bootloader by running:
>
> arm-none-linux-gnueabi-ld -static -nostdlib -T rockbox_bootloader_layout.txt -L $(dirname $(gcc -print-libgcc-file-name)) -lgcc *.o -o bootloader.elf
>
> Then, create rockbox_bootloader_layout.txt:
>
> ENTRY(_start)
>
> SECTIONS
> {
> /*
> * Locate the .start section at the address 0x41F00000
> */
> . = 0x41F00000;
> .start : { KEEP(*(.start)) }
>
> . = ALIGN(32);
> .text : { KEEP(*(.text)) }
>
> . = ALIGN(32);
> .rodata : { KEEP(*(.rodata)) }
>
> . = ALIGN(32);