diff --git a/README b/README index e8612b0..d9bd19d 100644 --- a/README +++ b/README @@ -22,6 +22,12 @@ And the schematic for the board http://www.raspberrypi.org/wp-content/uploads/2012/04/Raspberry-Pi-Schematics-R1.0.pdf (might be an old link, find the one on the wiki page) +The manual uses addresses like 0x7Exxxxxx, which is the real address for +something. But there is an address translation layer between the ARM +physical address and the real address. All of this code will use the +ARM physical address which is 0x20xxxxxx. The rest of the address is +the same so if the manual says 0x7E123456, then from the ARM use 0x20123456 + I dont normally use .data nor gcc libraries nor C libraries so you can build most if not all of my examples using a gcc cross compilerl. Basically it doesnt matter if you use arm-none-linux-gnueabi or arm-none-eabi. @@ -31,6 +37,74 @@ easy to use but you can use it. Building your own toolchain from gnu sources (binutils and gcc) is fairly straight forward and at some point will create a script to do that for you. +As far as we know so far the Raspberry Pi is not "brickable". Normally +what brickable means is the processor relies on a boot flash. For example +there may be a bootloader that allows you to re-program the flash. If you +make a mistake writing code at this low level and load the boot flash +with that bad code you may not be able to reload the flash again. There +are many ways to prevent this, but there are also still boards that +can be bricked or at least require more equipment or soldering, etc to +recover them. They way this board works is quite interesting. There +is a GPU on chip that boots from an on chip flash (in that respect it +may be brickable, but we dont have access to that GPU boot loader). The +GPU on chip bootloader looks for an sd card, the sd card contains more +GPU code. That code probably initializes sdram, and then copies the +contents of kernel.img on the sd card to sdram. Then releases reset +on the ARM. Each of these example programs produce a .bin file. +kernel.img is nothing more than a .bin file, an image of the flash. +The filename is special to the raspi bootloder, so you need to use +that file name. Backup your original kernel.img if you want to go back +to playing with linux then copy the .bin file in the example to +kernel.img on the sd card. For example +cp blinker01.bin /media/9876-5432/kernel.img +sync +umount /media/9876-5432 +Insert the sd card into the raspi and power. + +It wont take you very long to figure out this is going to get painful. + +1) power off raspi +2) remove sd card +3) insert sd card in reader +4) plug reader into computer +5) mount/wait +6) copy binary file to kernel.img +7) sync/wait +8) unmount +9) insert sd card in raspi +10) power raspi +11) repeat + +There are ways to avoid this, one is jtag, which is not as expensive +as it used to be. It used to be in the thousands of dollars, now it +is under $50 and the software tools are free. Now the raspi does have +jtag on the arm, getting the jtag connected to that is going to require +some soldering. I have not done it yet but will and will post info. +Unfortunately the connection to jtag is not there on power up you have +to run some code on the arm, so when that happens I will post that +program. + +Another method is a bootloader, typically you connect a serial port. +The program that actually boots on the processor has some way for you +to get into a bootloader. Sometimes that is all that is there, sometimes +you have to hit a key within a few seconds after it starts to boot. +The bootloader will have some way for you to use either the serial +or ethernet to copy a file into memory or flash. In this case probably +memory. I have a bootloader that works. Am working on a second one +that will probably be easier/better to use. With the bootloader method +at least how I am implementing it for the raspi, you perform the sd +card dance above one time to copy the bootloader to the sd card. You +use some flavor of serial port as described below. When the board +boots you can load your programs over the serial connection, never +needing to do the sd card dance until you want to leave your application +on the raspi and not the bootloader. The bootloader step will be +something like: + +1) power off raspi +2) power on raspi +3) type command to load and start new program + + My first bootloader is working, this will greatly save on wear and tear on the sd card socket. You will need some sort of serial adapter. The uart signals on the raspi are not at RS232 levels, you CANNOT @@ -58,5 +132,5 @@ going to work on a terminal based bootloder with xmodem, instead of the proprietary solution in bootloader01. I recommend you start with blinker01 and follow the discovery through -those to uart01, etc. Now that I have the bootloader working I have -to go back through these and generate a .hex file as well as a .img file. +those to uart01, etc. If you dont have a bootloader, do the sd card +dance with the .bin file. If you have a bootloader use the .hex file. diff --git a/blinker01/Makefile b/blinker01/Makefile index 89bd760..5f274e8 100644 --- a/blinker01/Makefile +++ b/blinker01/Makefile @@ -3,11 +3,12 @@ ARMGNU ?= arm-none-eabi COPS = -Wall -O2 -nostdlib -nostartfiles -ffreestanding -all : kernel.img +all : blinker01.hex blinker01.bin clean : rm -f *.o rm -f *.bin + rm -f *.hex rm -f *.elf rm -f *.list rm -f *.img @@ -18,10 +19,15 @@ novectors.o : novectors.s blinker01.o : blinker01.c $(ARMGNU)-gcc $(COPS) -c blinker01.c -o blinker01.o -kernel.img : memmap novectors.o blinker01.o +blinker01.elf : memmap novectors.o blinker01.o $(ARMGNU)-ld novectors.o blinker01.o -T memmap -o blinker01.elf $(ARMGNU)-objdump -D blinker01.elf > blinker01.list - $(ARMGNU)-objcopy blinker01.elf -O binary kernel.img + +blinker01.bin : blinker01.elf + $(ARMGNU)-objcopy blinker01.elf -O binary blinker01.bin + +blinker01.hex : blinker01.elf + $(ARMGNU)-objcopy blinker01.elf -O ihex blinker01.hex diff --git a/blinker01/README b/blinker01/README index 396722b..0fe2883 100644 --- a/blinker01/README +++ b/blinker01/README @@ -1,45 +1,18 @@ See the top level README for information on where to find the schematic and programmers reference manual for the ARM processor -on the raspberry pi. - -Based on some web searches the gpio is based at address 0x20200000 not -0x7E200000 as shown in the documentation. I have to go figure that out. - -Apparently what they have done is have the thing boot using the gpu -in the part, dont bother, leave it be, they are not going to let us -program it, not for a while at least. There is I assume a gpu bootloader -programmed in the chip, an OTP ROM based on something I read. This -searches for the sd card, and I assume loads another gpu bootloader -from that, at some point, the arm memory is loaded from kernel.img -on the sd card, then the ARM is released from reset. - -This simple example, sets up a small stack, not much to this program, and -I have not read up on how much memory is actually in this space. It -then enables gpio16 as an output. Then goes into a loop that sets -the gpio, waits, resets it, waits, repeat. gpio16 is shown on the -schematic to connect to the OK led. One of the bank of leds on the -corner near the audio out and host usb ports. The blink rate -for me is a few blinks a second perhaps. Future examples will get -use a timer if there is one and narrow in on the clock setup, etc. - -Copy the kernel.img file to the sd card, overwriting whatever you had -there. You may wish to backup the one you had there before you started -playing at this level. - -The beauty of this boot design is that it is not (easily) brickable, -so far as we know. With ignorance being bliss I will say it is not -brickable. Second we have no flash on the card we always run out of -ram as far as we are concerned. Making the board cheaper among other -things. The negative side to this is the development process is very -painful. It goes back to the GBA or NDS days, actually it was more -painful then. Here you unplug the rpi, pull the sd card out, put -the sd card in an sd card reader, plug the sd card reader into the -computer, wait or mount, copy kernel.img to the sd card, wait or sync, -unmount the sd card, remove the sd card reader, remove the sd card -place in rpi, plug in rpi. And repeat with each new build. I hope -to get the uart figured out and a bootloader so that I/we only have -to do that once, and from there on power off, power on, load the -program over serial. Not to dissimilar to the arduino experience. +on the raspberry pi. Also find information on how to load and run +these programs. +This simple example sets up a small stack, not much to this program +so the stack doesnt need much room. It then enables gpio16 as +an output. Then goes into a loop that sets the gpio, waits, resets it, +waits, repeat. gpio16 is shown on the schematic to connect to the OK +led. One of the bank of leds on the corner near the audio out and host +usb ports. The blink rate for me is a few blinks a second perhaps. +Future examples will get use a timer if there is one and narrow in on +the clock setup, etc. +novectors.s is the entry point for this code. This just gets things +started then calls a C function (blinker01.c) where the bulk of the +program is found. diff --git a/blinker02/Makefile b/blinker02/Makefile index 756ef73..6ca349e 100644 --- a/blinker02/Makefile +++ b/blinker02/Makefile @@ -3,11 +3,12 @@ ARMGNU ?= arm-none-eabi COPS = -Wall -O2 -nostdlib -nostartfiles -ffreestanding -all : kernel.img +all : blinker02.hex blinker02.bin clean : rm -f *.o rm -f *.bin + rm -f *.hex rm -f *.elf rm -f *.list rm -f *.img @@ -18,13 +19,13 @@ novectors.o : novectors.s blinker02.o : blinker02.c $(ARMGNU)-gcc $(COPS) -c blinker02.c -o blinker02.o -kernel.img : memmap novectors.o blinker02.o +blinker02.elf : memmap novectors.o blinker02.o $(ARMGNU)-ld novectors.o blinker02.o -T memmap -o blinker02.elf $(ARMGNU)-objdump -D blinker02.elf > blinker02.list - $(ARMGNU)-objcopy blinker02.elf -O binary kernel.img - - - +blinker02.bin : blinker02.elf + $(ARMGNU)-objcopy blinker02.elf -O binary blinker02.bin +blinker02.hex : blinker02.elf + $(ARMGNU)-objcopy blinker02.elf -O ihex blinker02.hex diff --git a/blinker02/README b/blinker02/README index 3a39192..3f9fc53 100644 --- a/blinker02/README +++ b/blinker02/README @@ -1,17 +1,14 @@ See the top level README for information on where to find the schematic and programmers reference manual for the ARM processor -on the raspberry pi. - -Based on some web searches the gpio is based at address 0x20200000 not -0x7E200000 as shown in the documentation. I have to go figure that out. +on the raspberry pi. Also find information on how to load and run +these programs. There is a free-running 64 bit timer, super easy to use, just read it. Based on a couple of experiments, without messing with anything it appears that the timer is runing at about a megahertz, 1 million ticks -per second. I am guessing it is divided down from the 700MHz somewhere, -will dig deeper. +per second. Hmm, there are comments in the manual about the system clock coming up at 250MHz. I wonder if this system timer is 250MHz/256 = 0.976MHz. diff --git a/blinker03/Makefile b/blinker03/Makefile index cf18563..88b7499 100644 --- a/blinker03/Makefile +++ b/blinker03/Makefile @@ -3,11 +3,12 @@ ARMGNU ?= arm-none-eabi COPS = -Wall -O2 -nostdlib -nostartfiles -ffreestanding -all : kernel.img +all : blinker03.hex blinker03.bin clean : rm -f *.o rm -f *.bin + rm -f *.hex rm -f *.elf rm -f *.list rm -f *.img @@ -18,13 +19,13 @@ novectors.o : novectors.s blinker03.o : blinker03.c $(ARMGNU)-gcc $(COPS) -c blinker03.c -o blinker03.o -kernel.img : memmap novectors.o blinker03.o +blinker03.elf : memmap novectors.o blinker03.o $(ARMGNU)-ld novectors.o blinker03.o -T memmap -o blinker03.elf $(ARMGNU)-objdump -D blinker03.elf > blinker03.list - $(ARMGNU)-objcopy blinker03.elf -O binary kernel.img - - - +blinker03.bin : blinker03.elf + $(ARMGNU)-objcopy blinker03.elf -O binary blinker03.bin +blinker03.hex : blinker03.elf + $(ARMGNU)-objcopy blinker03.elf -O ihex blinker03.hex diff --git a/blinker03/README b/blinker03/README index 92d2aaa..c2cc65f 100644 --- a/blinker03/README +++ b/blinker03/README @@ -1,7 +1,8 @@ See the top level README for information on where to find the schematic and programmers reference manual for the ARM processor -on the raspberry pi. +on the raspberry pi. Also find information on how to load and run +these programs. This example uses the free running ARM timer, not the 64 bit system one as in blinker02 but the so called ARM timer. diff --git a/uart01/Makefile b/uart01/Makefile index ace0626..e67739d 100644 --- a/uart01/Makefile +++ b/uart01/Makefile @@ -3,11 +3,12 @@ ARMGNU ?= arm-none-eabi COPS = -Wall -O2 -nostdlib -nostartfiles -ffreestanding -all : kernel.img +all : uart01.hex uart01.bin clean : rm -f *.o rm -f *.bin + rm -f *.hex rm -f *.elf rm -f *.list rm -f *.img @@ -18,12 +19,15 @@ novectors.o : novectors.s uart01.o : uart01.c $(ARMGNU)-gcc $(COPS) -c uart01.c -o uart01.o -kernel.img : memmap novectors.o uart01.o +uart01.elf : memmap novectors.o uart01.o $(ARMGNU)-ld novectors.o uart01.o -T memmap -o uart01.elf $(ARMGNU)-objdump -D uart01.elf > uart01.list - $(ARMGNU)-objcopy uart01.elf -O binary kernel.img - - + +uart01.bin : uart01.elf + $(ARMGNU)-objcopy uart01.elf -O binary uart01.bin + +uart01.hex : uart01.elf + $(ARMGNU)-objcopy uart01.elf -O ihex uart01.hex diff --git a/uart01/README b/uart01/README index 3b3f62d..23100ca 100644 --- a/uart01/README +++ b/uart01/README @@ -1,7 +1,8 @@ See the top level README for information on where to find the schematic and programmers reference manual for the ARM processor -on the raspberry pi. +on the raspberry pi. Also find information on how to load and run +these programs. Okay this was incredibly painful. I might have saved a few hours if was at the office with an oscilloscope, I eventually had to fashion @@ -15,11 +16,8 @@ do not do anything, they might on real 16550's but not here. Well that is wrong. If bits 1:0 are 00 you get 7 bits if bits 1:0 are 01 you get 7 bits. You need bit 1 set to get 8 bits. -This example uses the mini uart, uart1, to transmit characters on -GPIO14. You will need a level shifter or something that can receive -3.3v. One like this http://www.sparkfun.com/products/718 works perfectly. -Connect ground to pin 6 of P1 and rx on the FTDI board to tx on the -raspi which is pin 8 on the P1 connector. +See the top level README for information about connecting your host +computer to the uart on the raspi. This example sets up the uart for 115200 baud, and blasts the characters 0123456701234567...forever as fast as it can. diff --git a/uart02/Makefile b/uart02/Makefile index 4759426..59ed2b4 100644 --- a/uart02/Makefile +++ b/uart02/Makefile @@ -3,11 +3,12 @@ ARMGNU ?= arm-none-eabi COPS = -Wall -O2 -nostdlib -nostartfiles -ffreestanding -all : kernel.img +all : uart02.hex uart02.bin clean : rm -f *.o rm -f *.bin + rm -f *.hex rm -f *.elf rm -f *.list rm -f *.img @@ -18,13 +19,13 @@ novectors.o : novectors.s uart02.o : uart02.c $(ARMGNU)-gcc $(COPS) -c uart02.c -o uart02.o -kernel.img : memmap novectors.o uart02.o +uart02.elf : memmap novectors.o uart02.o $(ARMGNU)-ld novectors.o uart02.o -T memmap -o uart02.elf $(ARMGNU)-objdump -D uart02.elf > uart02.list - $(ARMGNU)-objcopy uart02.elf -O binary kernel.img - - - +uart02.bin : uart02.elf + $(ARMGNU)-objcopy uart02.elf -O binary uart02.bin +uart02.hex : uart02.elf + $(ARMGNU)-objcopy uart02.elf -O ihex uart02.hex diff --git a/uart02/README b/uart02/README index 8443a5e..5727140 100644 --- a/uart02/README +++ b/uart02/README @@ -1,20 +1,15 @@ See the top level README for information on where to find the schematic and programmers reference manual for the ARM processor -on the raspberry pi. +on the raspberry pi. Also find information on how to load and run +these programs. Based on uart01, this one enables the uart rxd1 receiver (gpio15). It starts by printing 12345678 then whatever you type on the terminal is echoed back. -You will need something like this -http://www.sparkfun.com/products/718 -to connect to the uart pins on the raspi. Do not connect the raspberry -pi pins directly to a com port on a computer you will fry the board. -The above board happens to have pins in the same order as the raspberry -pi. On connector P1 on the raspberry pi connect pin 6 to ground on the -usb to serial board. Pin 8 on P1 to RX on the usb to serial board, and -pin 10 on P1 to TX on the usb to serial board. +See the top level README file for information on how to connect the +raspi uart to your host computer. Using a dumb terminal (minicom) 115200 board No parity 8 bits 1 stop bit, no flow control (might have to exit minicom and start again for diff --git a/uart03/Makefile b/uart03/Makefile index a81b7cb..94027a3 100644 --- a/uart03/Makefile +++ b/uart03/Makefile @@ -3,7 +3,7 @@ ARMGNU ?= arm-none-eabi COPS = -mthumb -Wall -O2 -nostdlib -nostartfiles -ffreestanding -all : uart03.hex +all : uart03.hex uart03.bin clean : rm -f *.o @@ -19,14 +19,14 @@ novectors.o : novectors.s uart03.o : uart03.c $(ARMGNU)-gcc $(COPS) -c uart03.c -o uart03.o -uart03.hex : memmap novectors.o uart03.o +uart03.elf : memmap novectors.o uart03.o $(ARMGNU)-ld novectors.o uart03.o -T memmap -o uart03.elf $(ARMGNU)-objdump -D uart03.elf > uart03.list + +uart03.bin : uart03.elf $(ARMGNU)-objcopy uart03.elf -O binary uart03.bin + +uart03.hex : uart03.elf $(ARMGNU)-objcopy uart03.elf -O ihex uart03.hex - - - - diff --git a/uart03/README b/uart03/README index cf9c1bb..72c2933 100644 --- a/uart03/README +++ b/uart03/README @@ -1,7 +1,8 @@ See the top level README for information on where to find the schematic and programmers reference manual for the ARM processor -on the raspberry pi. +on the raspberry pi. Also find information on how to load and run +these programs. Based on uart02, the difference is that this is primarily thumb code instead of ARM. ARM in this case meaning the traditional 32 bit @@ -10,21 +11,5 @@ subset. Thumb2 has confused/blurred those definitions though. (thumb2 is a mostly 32 bit extension to the thumb instruction set using formerly undefined instructions to create variable word length instructions). -You have two choices you can use my bootloader with the uart03.hex file -or copy the uart02.bin file to (overwrite the) kernel.img on your raspi -sd card. (might want to back up that file if you want to go back to -running linux with it later, or download a replacement from the net). - -You will need something like this -http://www.sparkfun.com/products/718 -to connect to the uart pins on the raspi. Do not connect the raspberry -pi pins directly to a com port on a computer you will fry the board. -The above board happens to have pins in the same order as the raspberry -pi. On connector P1 on the raspberry pi connect pin 6 to ground on the -usb to serial board. Pin 8 on P1 to RX on the usb to serial board, and -pin 10 on P1 to TX on the usb to serial board. - -Using a dumb terminal (minicom) 115200 board No parity 8 bits 1 stop -bit, no flow control (might have to exit minicom and start again for -the flow control setting to take). What you type on the dumb terminal -echos back. +See the top level README for information on how to connect the raspi +uart to your host computer.