If you’ve been following our other articles on the SPMP8k-based PMP devices, then you’ve probably already disassembled your device, poked around in the RedBoot console, dumped some memory, and crashed the device in clever and interesting ways. Congratulations!
At this point, you’re probably ready to do some actual development. Great! One thing you may come to realize (if this is your first embedded project) is that you start with NOTHING. Absolutely nothing. You can write all the software you want, but if you are writing in C you will quickly find that even the most trivial built-in functions need to be implemented specifically for your device. We’ll start this article with a short discussion of how to get a small toolbox full of functions, and then continue with a C example program that can use those functions.
The end result of all this effort will be a console interaction such as the following.
RedBoot> go -c 0×200000
+do_go
image sel: 0, image_sel_set: 0
rmvb enable!
Mask interrupts on all channels
ID-CACHE sync and invalidate
set up a temporary context. workspace_end=0x00effdd0, entry=0×00200000
switch context to trampoline. workspace_end=0x00effd80Hello World, SPMP8k is alive!
Enter some text to see if I can read.
I’ll set the timeout to about 30 seconds for you slowpokes
Input> I am a hax0r of ultimate skillzResult was 0×1, your input was
I am a hax0r of ultimate skillz
Done… Bye!Program completed with status 0
RedBoot>
Awesome. Gratuitous self indulgence using only two functions: printf and gets. Should be a breeze.
Let’s first consider printf – Printf has grown to quite a sophisticated function, parsing an arbitrary number of parameters, formatting, converting variables to various types of ASCII output. You can find printf source code online, but it always depends on another function called putc – put character.
This is the even lower-level guy, taking one character from your string and doing the grunt work of getting it displayed. This is custom for each device and usually consists of things like checking a display buffer (or UART buffer in our case of serial port), setting up the device, stuffing our character into a register, and optionally marking or signalling that there is now a new character for the hardware device to display. Whew!
You can certainly write the code to do this type of thing, but it takes some work and is probably not suitable for a beginner. If you have the skills – go for it! But if you’re just starting out and your head is already swimming, let us show you a little cheat.
Since we presently need to have RedBoot running to execute a program anyway, we can just call RedBoot’s printf function. In fact, by downloading the RedBoot source code you can look up all the support functions it contains, and how to call them. Now THAT’s a hell of a jump start.
The only remaining requirement is to find where those functions are located in RAM while RedBoot is running. Our first program will act as a little parasite that will attach to Redboot and call it’s functions. In order to call those functions, we must locate ourselves in memory close enough to call RedBoot, but far enough away that if we start making variables, buffers, our stuff does not overwrite RedBoot’s memory. That sometimes causes spectacular crashes and interesting hangups, but is mostly just a pain in the ass.
Keep in mind that your device may have a different RedBoot version, or may have a different memory layout. When you start calling memory locations directly, you’ve got to make sure you have the right one.
You will first need a RAM dump of the section of memory that contains RedBoot. You get a hint during the startup text when you see the line that says:
RAM: 0×00000000-0x00f00000, [0x00200000-0x00f00000] available
It looks like RedBoot has taken the first 2MB for itself, and left the user the next 14MB. In order to be safe, we should dump the entire section – we’ll find RedBoot’s exact location later. Tell your terminal program to start capturing text, and fire the incredibly slow dump of the first 2MB.
RedBoot> dump -b 0×0 -l 0×200000
Go do something else for about ten minutes, or sit around and watch glassy-eyed as the text scrolls past. An alternative dump method would be to use arm-elf-gdb if you have it. Just disconnect your terminal software and use the following commands, where is the /dev/ name or COMx name of the PC serial port you are using.
arm-elf-gdb
(gdb) target remote
Remote debugging using
0x0003bcd0 in ?? ()
(gdb) dump binary memory myfile.bin 0×0 0x1fffff
We found long dumps to be problematic in gdb, which is a bummer because we use it almost exclusively for everything else.
Continued on Next Page… Jump to Page 2



Recent Comments