Jason Xu 9c5c2813a0 Update QEMU command in all README and Makefile 2 سال پیش
..
Makefile 426205e2a3 Added makefiles for LLVM Clang 5 سال پیش
Makefile.clang 9c5c2813a0 Update QEMU command in all README and Makefile 2 سال پیش
Makefile.gcc 9c5c2813a0 Update QEMU command in all README and Makefile 2 سال پیش
OLVASSEL.md 9c5c2813a0 Update QEMU command in all README and Makefile 2 سال پیش
README.md 9c5c2813a0 Update QEMU command in all README and Makefile 2 سال پیش
exc.c 2fc348ba46 Fixed typos and more tutorials 6 سال پیش
gpio.h 2fc348ba46 Fixed typos and more tutorials 6 سال پیش
kernel8.img 8ce0f75b47 Recompiled with latest gcc 4 سال پیش
link.ld 2fc348ba46 Fixed typos and more tutorials 6 سال پیش
main.c 2fc348ba46 Fixed typos and more tutorials 6 سال پیش
mbox.c 214885df63 compute the mailbox cmd only once 6 سال پیش
mbox.h 2fc348ba46 Fixed typos and more tutorials 6 سال پیش
mmu.c 1cc441850b no further cast to "(unsigned long)" needed 6 سال پیش
mmu.h 2fc348ba46 Fixed typos and more tutorials 6 سال پیش
start.S ea4691947c Improve comments wrt stack setup 3 سال پیش
uart.c c59ad439f4 Enable UART0 FIFOs 3 سال پیش
uart.h 2fc348ba46 Fixed typos and more tutorials 6 سال پیش

README.md

Tutorial 11 - Exceptions

Last time we have used a very simple translation scheme, but in real life you often need more. And it is not easy to write the table blindly, so we're going to add exception handlers this time. This will print out some system registers to identify the problem with our translation tables.

$ qemu-system-aarch64 -M raspi3b -kernel kernel8.img -serial stdio
Synchronous: Data abort, same EL, Translation fault at level 2:
  ESR_EL1 0000000096000006 ELR_EL1 0000000000080D7C
 SPSR_EL1 00000000200003C4 FAR_EL1 FFFFFFFFFF000000

Here ESR_EL1 tells us that it was a Data Abort, caused by a translation table error at level 2. The instruction triggered it is at address 0x80D7C which tried to access memory at 0xFFFFFFFFFF000000.

The vector is very similar to AMD64's IDT, with two exceptions: first, there's no special instruction (like sidt), but a system register stores the address. Second, we don't pass a table with addresses rather the address of the actual code. Therefore each "entry" of the vector table is bigger, small stubs so that you can set up arguments and jump to a common handler.

On AMD64 you have 32 entry points for each exception. On AArch, you only have one, and you can read the excpetion code from a system register. Considering that all OS sets a code for the exception and jumps to a common handler, this makes life easier.

Exc.c

exc_handler() a simple exception handler that dumps registers and decodes ESR_EL1 (partially). We simply stop the CPU for now, as we have no means to recover from an exception yet. The full comprehensive description of Exception Syndrome Register can be found in ARM DDI0487B_b chapter D10.2.28.

Start

Before we switch to supervisor mode, we set up vbar_el1. All handlers must be properly aligned. Qemu is not so picky, but real hardware is.

_vectors the exception handler's vector table with small assembly stubs, each calling exc_handler() in C.

Main

We set up page translations, and then we deliberatly reference an unmapped address to trigger an exception.