Let's start with the linker script

Linker scripts have some prerequisite knowledge

  1. Combine from multiple source files into one output file
  2. Each object file has its own defined section list (ie 1. text section 2. data section …)

linker script

We need to manually specify the location of each section.

SECTIONS { . = 0x80000; .text : { *(.text) } }

Since the architecture is aarch64, the default load address is 0x80000.
As you can see, our kernel is very simple, with only one text section (ie assembly file)

So ".text" is defined, and the location must be appended to 0x80000

asm file

.section ".text" .global _start _start: wfe b _start

This is a simple assembly code that defines "_start" as a global.

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

So the type of _start is bound to GLOBAL.

This is important because we need this symbol to find which part of the code will be the first instruction

At this point, we have completed the above files, and now we can compile them and start it in the qemu system.

qemu-system-aarch64 -M raspi3 -kernel kernel8.img -display none -serial null -serial stdio -S -s

We started a simple kernel through the qemu system,
But how to check the running status?

Yes, GDB is here

$ gdb $ (gdb) target remote :1234

As you can see, the process is attached.

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Well, look at the instructions and you will know that the code is the same as our asm file.

The address also starts with 0x80000, because our linker script defines the location counter as 0x80000, and the text section follows the counter.


@ arm platform series - 1

tags: CY