Booting Raspberry Pi 3: Difference between revisions

no edit summary
[unchecked revision][unchecked revision]
No edit summary
No edit summary
 
(3 intermediate revisions by 2 users not shown)
Line 2:
{{Spelling}}
{{FirstPerson}}
{{You}}
{{Rating|1}}
This is a tutorial on bare-metal OS development on the Raspberry Pi 3 (RPi 3).
Line 33 ⟶ 34:
There is also another file required to boot properly. A config.txt file must be supplied to provide configuration details for the device and the OS. Here are the only entries you need:
 
<sourcesyntaxhighlight lang="ini">
boot_delay=1
force_turbo=1
enable_uart=1
</syntaxhighlight>
</source>
 
More details about booting and configuration can be found at thse links.
Line 66 ⟶ 67:
 
'''The start address and alignment are for the RPi3. Use whatever is applicable to you.'''
<sourcesyntaxhighlight lang="c">
SECTIONS
{
Line 88 ⟶ 89:
}
}
</syntaxhighlight>
</source>
 
== Booting the Kernel ==
Line 94 ⟶ 95:
For the RPi 3, after the start.elf finishes, the CPU and SRAM have been enabled and control is given to the kernel image. But there are a few things we must do in order to set up a basic C environment. This is known as a bootstrap stage which initializes our OS and programming environment on startup and hands control to the kernel. Keep in mind that this is for a minimalistic development environment on a single core.
 
<sourcesyntaxhighlight lang="asm">
.section .boot
 
Line 105 ⟶ 106:
0: wfe
b 0b
</syntaxhighlight>
</source>
 
The mrs instruction loads data from specialty registers into a standard register. This special register in question is called the MPIDR or the Multiprocessor Affinity Register. Caring only about the first two bits only we use a bitwise and to weed out any core ID's that aren't zero. Then we apply the cbz instruction, which is a shorthand instruction for comparing the x4 register with 0 and branching if they are equal, i.e. core 0.
Line 111 ⟶ 112:
If the core ID is 0, we branch to another section that will initialize the environment and will hand control over to the kernel. For now, the C function for our kernel will simply by kern_main.
 
<sourcesyntaxhighlight lang="asm">
_init: ldr x4, =_start
mov sp, x4
b kern_main
</syntaxhighlight>
</source>
 
Note that with the latest firmware, this is not necessary, as only the primary core runs. It is enough to set up stack and branch to kern_main.
 
<sourcesyntaxhighlight lang="asm">
// for latest firmware, after 2020-01-01
.section .boot
Line 128 ⟶ 129:
mov sp, x4
b kern_main
</syntaxhighlight>
</source>
 
== Writing the Kernel ==
Line 134 ⟶ 135:
The kernel is as simple as creating a kern_main function for the bootstrap stage to transfer control to. You notice that in start.S we have the program branch into the function. All we need to do is provide one.
 
<sourcesyntaxhighlight lang="c">
 
#include <stdbool.h>
Line 143 ⟶ 144:
while (true);
}
</syntaxhighlight>
</source>
 
== Conclusion ==
Line 154 ⟶ 155:
* [[Raspberry Pi Bare Bones]] - a much more detailed introduction to booting on Raspberry Pi
 
[[Category: Raspberry Pi]]
[[Category:Booting]]