SPMP8k Development - Hello World, parasitic version
QRCode
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=0×00effdd0, entry=0×00200000
switch context to trampoline. workspace_end=0×00effd80Hello 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-0×00f00000, [0×00200000-0×00f00000] 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
0×0003bcd0 in ?? ()
(gdb) dump binary memory myfile.bin 0×0 0×1fffff
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
Related Posts:
Metadata:





January 27, 2010 @ 7:56 am
Very interesting stuff , I’m so anxious to try this but unfortunately I can’t do it a work.
There are some things that don’t seem that clear right now but once I try and actually do it I’ll give my opinions on this.
January 29, 2010 @ 9:57 pm
First of all thank you for this nice tutorial , don’t know where I could have gotten all the info I needed. It is indeed available if you search but not in one nice reading.
I did have some problems though
GDB ( arm-elf-gdb (GDB) 7.0 running on Linux ) shows too much gibberish each time I connect to the remote target.
arm-elf-gdb -v
GNU gdb (GDB) 7.0
Sending packet: $Hg0#df…[+]Ack
[$][O][K][#][9][a]Packet received: OK
Sending packet: $?#3f…[+]Ac
Any idea how to turn all this nonsense off ?
Second I’ve had to also set these options in order to connect:
set remotebaud 115200
set debug remote 1
set debug serial 1
It’s probably setting of the remotebaud that’s really important , your article doesn’t say anything about this. I do understand that you were in hurry , I just think it’s something that could have been said ( I needed it ).
And last of you might think we know about this but what follows after load in gdb ? I did try continue but I’m not to satisfied with that . Something that just executes the program and then returns like go in Redboot would be nice.
And something intresting , it seems that the printf function I’m using which has the prototype you said it should keeps asking to continue(y/n) after each line that’s printed ( I just found this an interesting fact ).
January 29, 2010 @ 11:51 pm
Marius:
Glad to hear you’re making progress! We’ll try to give more detailed in upcoming articles, but it’s great that you were able to debug baud rate and connection settings by yourself - kudos!
The gibberish is the actual gdb packets sent and received from the device. I don’t know how it was turned on, but I believe you can turn it off with:
set remotedebug 0
As far as the connection options, gdb will use the default options of the port. Set up your hardware to default to 115.2k, 8, n, 1 and hardware flow control off. Then you should be able to connect with the simple
target remote COM1
After you load the file, quit gdb (but don’t power down the device) and use a terminal program like minicom or hyperterminal to reconnect to redboot. Hit enter to get the
RedBoot>
prompt, and launch the program with go -c 0x????. Where ???? is the entry point. In this case, the command is
RedBoot> go -c 0×200000
January 30, 2010 @ 12:41 am
Thanks for the answer. I have thought of that too but unfortunately once I disconnect it just seems that my console dies ( the board indicates that it’s a H802_V11 ) and production date is 2009.9.08. I’ve found it to be different than your model in other ways too ( start of printf and gets for instance ).
There is one cool thing though . I can connect to it using gdb under Linux but I must not disconnect the serial. I just connect with GDB and the serial connection gets dropped. I did get a stable 2 MB dump through GDB though after that , no problems whatsoever.
Seems to me that for some reason once I disconnect the serial it dies ,I can’t reconnect with serial and I cant connect with GDB. I’ve tried to disconnect with TeraTerm , Hyperteminal under Windows and Cutecom under Linux , same thing.
January 30, 2010 @ 1:01 am
Marius: It might not be dead, it might be stalled. Our PL-2303 USB serial port always stalls this thing, so now we use an FT232. Also, bad grounding by using the included USB cable can cause stalls and other weird stuff.
To recover from a stall, switch the device to ON and unplug/replug the USB. The device must be switched ON so it doesn’t immediately power down, of course.
In our case, the USB replug forces an “INQUIRY” which usually kicks RedBoot out of a stall and brings the console back to life.
January 30, 2010 @ 1:51 am
Thanks for the help and the advice but still no joy. It looks like after I disconnect it’s really dead, can’t connect anymore. Why that is I don’t know but I’ve noticed that for some reason it just seems to die.
My choice of connecting is much different though. The Nokia 3310 cloned serial cable might be playing some tricks here and maybe my choice of grounding is not the best , I’ve found a small pad near R99 , just under where the speaker should be. Seems to work just fine though , I never really get any errors ( that I’ve noticed ) and I even managed to get a full 2 MB dump. Only problem is when I connect.
Oh well, I guess the serial xmodem upload will have to do even though it has a delay to it , at least I don’t have to disconnect. I’m just wondering , is there any simple way to modify just that delay byte / bytes so the xmodem upload will be faster ?
Other than that it’s all pretty good, but I will try a Nokia USB to serial cable ( they’re cheap and easy to get ) too and see how that goes. Maybe I should choose a different grounding this time. The one from the USB port ?
Anyway don’t want to keep you from your hacking ( I know how that is ) so good luck to you ( seems we’ve had plenty of luck so far with the hacking ).
February 3, 2010 @ 12:40 am
When I try to compile I get these errors:
hello.c:1:20: error: stdlib.h: No such file or directory
hello.c:2:20: error: stdint.h: No such file or directory
I’m using the libspmp toolchain that you wrote about in a previous article. I’ve tried installing glibc-devel and my system indicates that I have stdlib.h and stdint.h in /usr/include