Skip to content

Commit e35d1e9

Browse files
committed
updated main readme
1 parent 501d486 commit e35d1e9

File tree

1 file changed

+124
-89
lines changed

1 file changed

+124
-89
lines changed

README

Lines changed: 124 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,58 @@ nor broadcom. I just happen to own one (some) and am sharing my
88
experiences. The raspberry pi is about education, and I feel bare
99
metal education is just as important as Python programming.
1010

11+
So I started this years ago when got my first ARM11 based raspberry pi
12+
maybe we call that a raspberry pi 1, I dont know a good term. But
13+
now there is a growing number of variations.
14+
15+
ARM11 based (BCM2835)
16+
Raspberry Pi B
17+
Raspberry Pi A+
18+
Raspberry Pi B+
19+
Raspberry Pi Zero
20+
Cortex-A7 based (BCM2836)
21+
Raspberry Pi 2 B
22+
23+
There is also the compute module but I dont have one of those.
24+
25+
General differences that we care about for these examples. The amount
26+
of ram varies from board to board. The peripheral base address is
27+
different between the BCM2835 and BCM2836. The BCM2835 looks for the
28+
file kernel.img the BCM2836 looks for kernel7.img. The ARM11 based
29+
Zero is a B with stuff removed and a new layout, but they up/over
30+
clocked the processor from 750MHz to 1000MHz, one led on gpio 16. The
31+
A+ and B+ they moved the led (or put two) on gpio 35 and 47. The
32+
raspberry pi 2 is B+ like but with the different chip, supposedly the
33+
BCM2836 is BCM2835 with the ARM11 core removed and replaced with
34+
the Cortex A7 and for the most part it appears to be.
35+
36+
As of this writing I am adding plus and pi2 versions of the examples
37+
as many of them are based on the early/original. No guarantees I will
38+
do that, just looking at the differences between the blinker01 examples
39+
should show you what to do to convert these yourself. In some cases
40+
I am intentionally not trying to have one code base build for all
41+
three with ifdefs and such, keep it simple stupid then complicate it
42+
as needed. The text may say kernel.img but substitute with kernel7.img
43+
as needed.
44+
45+
1146
From what we know so far there is a gpu on chip which:
1247

1348
1) boots off of an on chip rom of some sort
1449
2) reads the sd card and looks for additional gpu specific boot files
1550
bootcode.bin and start.elf in the root dir of the first partition
1651
(fat32 formatted, loader.bin no longer used/required)
1752
3) in the same dir it looks for config.txt which you can do things like
18-
change the arm speed from the default 700MHz, change the address where
19-
to load kernel.img, and many others
53+
change the arm speed, or change the address where to load kernel.img,
54+
and many others
2055
4) it reads kernel.img the arm boot binary file and copies it to memory
2156
5) releases reset on the arm such that it runs from the address where
2257
the kernel.img data was written
2358

2459
The memory is split between the GPU and the ARM, I believe the default
2560
is to split the memory in half. And there are ways to change that
26-
split (to give the ARM more). Not going to worry about that here.
61+
split (to give the ARM more)(using config.txt). Not going to worry
62+
about that here.
2763

2864
From the ARMs perspective the kernel.img file is loaded, by default,
2965
to address 0x8000. (there are ways to change that, not going to worry
@@ -33,12 +69,18 @@ Hardware and programming information:
3369

3470
You will want to go here
3571
http://elinux.org/RPi_Hardware
36-
And get the datasheet for the part
37-
http://www.raspberrypi.org/wp-content/uploads/2012/02/BCM2835-ARM-Peripherals.pdf
38-
(might be an old link, find the one on the wiki page)
39-
And the schematic for the board
40-
http://www.raspberrypi.org/wp-content/uploads/2012/04/Raspberry-Pi-Schematics-R1.0.pdf
41-
(might be an old link, find the one on the wiki page)
72+
And the datasheet and schematic. These are moving targets the above
73+
elinux link has the datasheet and errata which is important. They
74+
didnt give us a full datasheet for the BCM2836 have to go with the
75+
BCM2835.
76+
You will want to go to
77+
http://raspberrypi.org and then the forum tab then slide down to
78+
the Bare Metal forum, the first (only) Sticky topic is Bare Metal
79+
Resources. There are many more links there for good information.
80+
Also go to
81+
http://infocenter.arm.com and get the Architectural Reference Manual
82+
and the Techincal Reference Manual for the ARM1176JZF-S (BCM2835)
83+
and/or the Cortex-A7 (BCM2836).
4284

4385
Early in the BCM2835 document you see a memory map. I am going to
4486
operate based on the middle map, this is how the ARM comes up. The
@@ -60,34 +102,46 @@ physical address. Experimentally I have seen the memory repeats every
60102
0x40000000, read 0x40008000 and you see the data from 0x8000. From the
61103
Broadcom doc this looks to be giving us access to the memory with
62104
different caching schemes (cached, uncached, etc) depending on which
63-
upper address bits you use.
105+
upper address bits you use. Most likely to allow more room for RAM
106+
the Raspberry Pi 2 uses a peripheral base address of 0x3Fxxxxxx instead
107+
of the 0x20xxxxxx.
64108

65-
I do not normally zero out .bss or use .data so if you do this to my examples
109+
I do not normally zero out .bss or use .data so if you do this to my
110+
examples
66111

67112
int x;
68113
fun()
69114
{
70115
static int y;
71116
}
72117

73-
dont assume x and y are zero when your program starts. Nor if you do this
118+
dont assume x and y are zero when your program starts. Nor if you do
119+
this
74120

75121
int x=5;
76122
fun()
77123
{
78124
static int y=7;
79125
}
80126

81-
will x=5 or y=7. See the bssdata directory for more information.
127+
will x=5 or y=7.
128+
129+
See the bssdata directory for more information, you can most likely
130+
use the linker script to solve the problem for you since .text, .data,
131+
.bss, (.rodata), everything lives in ram.
82132

83133
Nor do I use gcc libraries nor C libraries so you can build most if not
84134
all of my examples using a gcc cross compiler. Basically it doesnt
85-
matter if you use arm-none-linux-gnueabi or arm-none-eabi. What was
86-
formerly codesourcery.com still has a LITE version of their toolchain
87-
which is easy to come by, easy to install and well maybe not easy to use
88-
but you can use it. Building your own toolchain from gnu sources (binutils
89-
and gcc) is fairly straight forward see my build_gcc repository for a
90-
build script.
135+
matter if you use arm-none-linux-gnueabi or arm-none-eabi. I have not
136+
looked in a while but formerly codesourcery.com (now a part of Mentor
137+
Graphics) had a free LITE version of their toolchain which was pretty
138+
easy to come by. An even easier place is here
139+
https://launchpad.net/gcc-arm-embedded
140+
to get a cross compiler. Building your own toolchain from gnu sources
141+
(binutils and gcc) is fairly straight forward see my build_gcc
142+
repository for a build script (Linux only but from that you might get
143+
other platforms to build). And also rememeber that you can run linux
144+
on the pi and on that it has a native, not cross, gnu toolchain.
91145

92146
As far as we know so far the Raspberry Pi is not "brickable". Normally
93147
what brickable means is the processor relies on a boot flash and with
@@ -102,14 +156,19 @@ calculator, etc and you may see some holes or pads on the circuit board,
102156
for some of these devices just opening the battery case you have a view
103157
of some of the pcboard. This is no doubt a programming header. Long
104158
story short, so far as I know the Raspberry Pi is not brickable because
105-
the rom/flash that performs the initial boot is for the gpu and we dont
106-
have access to the gpu nor its boot rom/flash. The gpu relies on the
107-
sd card to complete the boot, so there is something in hardware or
108-
perhaps there is an on chip flash for the gpu, from there on it is all
109-
sd card. It is very easy for the customer to remove and
110-
replace/modify that boot flash. So from a software perspective
111-
unless you/we accidentally figure out how to change/erase the gpu boot
112-
code (my guess is it is a one time programmable) you cant brick it.
159+
it boots off of an sd card which we can easily remove and replace
160+
ourselves. I dont know for sure, a lot more info is out about the
161+
GPU since I started with this, but I assume that there is some GPU code
162+
that boots off of an internal rom, I doubt with two on chip processors
163+
they created pure logic to read the sd card, wade through the filesystem
164+
to find a specific bootcode.bin file, load that into ram and run it.
165+
If that assumption is true is that on chip rom one time programmable
166+
or can it be erased/reprogrammed, and if the latter how lucky do we have
167+
to be with a broken program to erase that? So I am not 100% sure but
168+
almost 100% sure the Raspberry Pi is not brickable. This is actually
169+
a big deal for bare metal programming, in particular if it is your first
170+
platform. With decades of experience I still make mistakes from time
171+
to time and brick a board, never to be recovered.
113172

114173
To use my samples you do not need a huge sd card. Nor do you need nor
115174
want to download one of the linux images, takes a while to download,
@@ -124,13 +183,14 @@ For each of these files, bootcode.bin and start.elf (NOT kernel.img,
124183
dont need it, too big)(loader.bin is no longer used/required). Click
125184
on the file name, it will go to another page then click on View Raw and
126185
it will let you download the file. For reference, I do not use nor
127-
have a config.txt file on my sd card. I only have the three files (
128-
bootcode.bin, start.elf, and then kernel.img from one of my examples).
186+
have a config.txt file on my sd card. I only have the minimum number
187+
of files on the sd card, bootcode.bin, start.elf and either kernel.img
188+
or kernel7.img (or sometimes both).
129189

130190
My examples are basically the kernel.img file. Not a linux kernel,
131191
just bare metal programs. Since the GPU bootloader is looking for
132192
that file name, you use that file name. The kernel.img file is just a
133-
blob that is copied to memory, nothing more.
193+
blob that is copied to memory, dont worry about what they named it.
134194

135195
What I do is setup the sd card with a single partition, fat32. And
136196
copy the above files in the root directory. bootcode.bin and start.elf.
@@ -153,9 +213,10 @@ this is going to get painful.
153213
There are ways to avoid this, one is jtag, which is not as expensive
154214
as it used to be. It used to be in the thousands of dollars, now it
155215
is under $50 and the software tools are free. Now the raspi does have
156-
jtag on the arm, getting the jtag connected requires soldering on some
157-
models, but not on the newer models. I do not yet have a newer model.
158-
How to use the jtag and how to hook it up is described later and in
216+
jtag on the arm, getting the jtag connected requires soldering on older
217+
of the older models, but unless you were an early adopter, you dont
218+
need to worry about that all the signals are on the P1 connector. How
219+
to use the jtag and how to hook it up is described later and in
159220
the armjtag sample.
160221

161222
Another method is a bootloader, typically you use a serial port connected
@@ -172,18 +233,32 @@ bootloader dance:
172233
2) power on raspi
173234
3) type command to load and start new program
174235

175-
I have working bootloader examples. bootloader05 is the currently
176-
recommended version. But you need more hardware (no soldering is
177-
required). For those old enough to know what a serial port is, you
178-
CANNOT connect your raspberry pi directly to this port, you will fry
179-
the raspberry pi. You need some sort of serial port at 3.3V either
180-
a level shifter of some sort (transceiver like a MAX232) or a usb
181-
serial port where the signals are 3.3V (dont need to use RS232 just
182-
stay at the logic level). The solution I recommend is a non-solder
236+
Or if you solder on a reset button
237+
238+
1) reset raspi
239+
2) type command to load and start new program
240+
241+
I have working bootloader examples. bootloader05 is currently the last
242+
of the xmodem based ones (that basically take a kernel.img file),
243+
personally I use bootloader07 which takes an intel hex formatted file
244+
which these examples also build. The .bin file would be used with
245+
bootloader05, the .hex with bootloader07. But you need more hardware
246+
(no soldering is required). For those old enough to know what a serial
247+
port is, you CANNOT connect your raspberry pi directly to this port,
248+
you will fry the raspberry pi. You need some sort of serial port at
249+
3.3V either a level shifter of some sort (transceiver like a MAX232) or
250+
a usb serial port where the signals are 3.3V (dont need to use RS232
251+
just stay at the logic level). The solution I recommend is a non-solder
183252
solution:
184253

185254
A recent purchase, experimentally white is RX and green is TX, black GND
186255
http://www.nexuscyber.com/usb-to-ttl-serial-debug-console-cable-for-raspberry-pi
256+
Sparkfun has one
257+
https://www.sparkfun.com/products/12977
258+
As does Adafruit
259+
https://www.adafruit.com/products/954
260+
The above, assuming you figure out rx from tx, are all you need. The
261+
ones below you may need to solder or may need some jumper wires.
187262

188263
http://www.sparkfun.com/products/9873
189264
plus some male/female wire
@@ -216,7 +291,7 @@ P1. Starting at that corner of the board, the outside corner pin is
216291
pin 2. From pin 2 heading toward the yellow rca connector the pins
217292
are 2, 4, 6, 8, 10. Pin 6 connect to gnd on the usb to serial board
218293
pin 8 is TX out of the raspi connect that to RX on the usb to serial
219-
board. pin 10 is RX into the raspi, connect that to TX on the usb to
294+
board. Pin 10 is RX into the raspi, connect that to TX on the usb to
220295
serial board. Careful not to have metal items on the usb to serial
221296
board touch metal items on the raspberry pi (other than the three
222297
connections described). On your host computer you will want to use
@@ -245,13 +320,14 @@ jtag solution is the most powerful and useful. My typical setup is the
245320
armjtag binary as kernel.img, a usb to jtag board like the amontec
246321
jtag-tiny and a usb to serial using minicom.
247322

323+
If you can solder, the A+, B+, Zero and Pi 2 all have a pair of holes
324+
sometimes with the text RUN next to them. I use buttons like this
325+
https://www.sparkfun.com/products/97
326+
with two of the legs broken off then the others twisted and adjusted
327+
to fit in the holes and soldered down.
328+
248329
As far as these samples go I recommend starting with blinker01 then
249-
follow the discovery of the chip into uart01, etc. I took one path
250-
with the first bootloader then switched gears to use xmodem, if
251-
interested at all you may wish to just skip to that one. It has no
252-
features and isnt even robust, quick and dirty, and most of the time
253-
it works just fine, if not power cycle the raspberry pi and try again.
254-
(power cycle = unplug then plug back in)
330+
follow the discovery of the chip into uart01, etc.
255331

256332
The bssdata and baremetal directories attempt to explain a little
257333
bit about taking control of the gnu toolchain to build bare metal
@@ -267,44 +343,3 @@ makes life a lot easier, but leaves out some important bare metal
267343
experiences that you will have to find elsewhere.
268344

269345
-----------
270-
271-
Sources for ARM ARMs
272-
273-
Google
274-
ARM DDI 0100E
275-
or
276-
ARM DDI 0100I
277-
278-
https://www.scss.tcd.ie/~waldroj/3d1/arm_arm.pdf
279-
http://morrow.ece.wisc.edu/ECE353/arm_reference/ddi0100e_arm_arm.pdf
280-
http://reds.heig-vd.ch/share/cours/aro/ARM_Thumb_instructions.pdf
281-
They have a rev B here...Which was the blue covered one in print. This
282-
was the I learned from (the print version) later I got a rev a, then
283-
rev e all in print then it was only electronic from there out as far as
284-
I know. the older ones being more pure, but also some notable bugs
285-
in the docs, instruction encodings and some other things.
286-
http://www.home.marutan.net/arcemdocs/
287-
288-
Actually the preferred place is to go to http://infocenter.arm.com
289-
On the left expand ARM Architecture, expand Reference Manuals, then
290-
select ARMv5 Reference Manual then on the main part of the page click
291-
on the pdf file to download. You might have to give up an email address
292-
to make an account on the site to download. Yes the Raspberry pi 1
293-
uses an ARMv6 but the ARMv5 manual is the original ARM ARM and covers
294-
the ARMv6. The raspberry pi 2 uses an ARMv7 so you will want to also
295-
or instead get the ARMv7-AR Reference Manual. The ARMv6-M does NOT
296-
apply to the Rasperry pi 1 core.
297-
298-
299-
I managed to get a pi zero ordered the first day somehow. And it works
300-
like the pi 1, I assume it is 1000mhz now instead of 750, but the
301-
peripheral clock for the uart still uses the same divisor and works.
302-
I did need to get a new bootcode.bin and start.elf, not sure how old
303-
the ones I had on the sd card were, but pulled new ones and the uart01
304-
example worked just fine. You do have to solder pins now or somehow
305-
solve that and I soldered a momentary button on the run pins and like
306-
the other boards those appear to be the reset.
307-
308-
309-
310-

0 commit comments

Comments
 (0)