You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
bzt a0b68d2db7 New tutorial, raspbootin for 64 bit 6 years ago
..
Makefile New tutorial, raspbootin for 64 bit 6 years ago
OLVASSEL.md New tutorial, raspbootin for 64 bit 6 years ago
README.md New tutorial, raspbootin for 64 bit 6 years ago
gpio.h New tutorial, raspbootin for 64 bit 6 years ago
kernel8.img New tutorial, raspbootin for 64 bit 6 years ago
link.ld New tutorial, raspbootin for 64 bit 6 years ago
main.c New tutorial, raspbootin for 64 bit 6 years ago
mbox.c New tutorial, raspbootin for 64 bit 6 years ago
mbox.h New tutorial, raspbootin for 64 bit 6 years ago
start.S New tutorial, raspbootin for 64 bit 6 years ago
uart.c New tutorial, raspbootin for 64 bit 6 years ago
uart.h New tutorial, raspbootin for 64 bit 6 years ago

README.md

Tutorial 15 - Raspbootin64

Because changing SD card is boring and also to avoid potential SD card damage, we create a kernel8.img that will load the real kernel8.img over serial.

This tutorial is a rewrite of the well known serial boot loader, raspbootin in 64 bit. I only provide one part of the loader, the kernel receiver, which runs on the RPi. For the other part, the sender, which runs on your PC see the original raspbootcom utility. If you want to send kernels from a Windows machine, I suggest to take a look at John Cronin's rewrite, raspbootin-server which can be compiled for the Win32 API.

In order to load the new kernel to the same address, we have to move ourself out of the way. It's called chain loading: one code loads the next code to the same position in memory, therefore the latter thinks it was loaded by the firmware. To implement that we use a different linking address this time, and since GPU loads us to 0x80000 regardless, we have to copy our code to that link address. That's important that we can only use relative addresses while doing so. When we're done, the memory at 0x80000 must be free to use. We also should minimize the size of the loader, since it will be regarded by the newlt loaded code anyway. By removing uart_puts() I've managed to shrink the size below 1024 bytes. I've checked that with:

$ aarch64-elf-readelf -s kernel8.elf | grep __bss_end
    21: 000000000007ffd0     0 NOTYPE  GLOBAL DEFAULT    4 __bss_end

Start

Added a loop to relocate our code to the address it should have been loaded to.

Linker

We use a different linking address this time. Similarly to bss size calculation, we calculate our code's size to know how many bytes we have to copy.

Main

We print 'RBIN64', receive the new kernel over serial, and jump to it.