aboutsummaryrefslogtreecommitdiff
path: root/kernel_stage1.S
diff options
context:
space:
mode:
authorWojtek Kosior <kwojtus@protonmail.com>2019-12-28 21:54:42 +0100
committerWojtek Kosior <kwojtus@protonmail.com>2019-12-28 21:54:42 +0100
commit700f4c412d42c9b9811269045c0e363a0331bba9 (patch)
tree260feed1ca657843d993c1ae73e93f25a17cede1 /kernel_stage1.S
parent80c9af17330ac442a4c3d6d55b4041cbe923e9b4 (diff)
downloadrpi-MMU-example-700f4c412d42c9b9811269045c0e363a0331bba9.tar.gz
rpi-MMU-example-700f4c412d42c9b9811269045c0e363a0331bba9.zip
split kernel into 2 stages; second stage gets copied to 0x0 and runs from there
Diffstat (limited to 'kernel_stage1.S')
-rw-r--r--kernel_stage1.S67
1 files changed, 67 insertions, 0 deletions
diff --git a/kernel_stage1.S b/kernel_stage1.S
new file mode 100644
index 0000000..1e0f614
--- /dev/null
+++ b/kernel_stage1.S
@@ -0,0 +1,67 @@
+/* arm mode, cortex-a7 compatibility
+ *
+ * _boot is entry point for the kernel.
+ *
+ * Kernel copies it's embedded stage 2 to address 0x0 and jumps to
+ * it (to the reset handler). Registers r0 - r2 are arguments for
+ * the kernel, but we're not using them for now.
+ *
+ * This file is based on (and almost identical with) loader_stage1.S
+ */
+
+.global _boot
+_boot:
+ // Only let the first core execute
+ mrc p15, 0, r3, c0, c0, 5
+ and r3, r3, #3
+ cmp r3, #0
+ beq proceed
+ // this is a kind of blef - races can theoretically still
+ // occur when the main core overwrites this part of memory
+ wfe
+
+proceed:
+ // copy stage2 of the kernel to address 0x0
+
+ // first, load address of stage2_start to r3 (a PIC way)
+ adr r3, stage2_start
+
+ // load destination address for stage2 code to r4
+ mov r4, #0
+
+ // load blob size to r5
+ // The size might get too big for an immediate value, so
+ // we load it from memory.
+ adr r5, blob_size
+ ldr r5, [r5]
+
+ // r6 is the counter - counts the bytes copied
+ mov r6, #0
+
+ // This initial piece of code might get overwritten when we
+ // copy stage2, so the actual copying loop shall be after
+ // stage2 blob. We want this asm code to be PIC, so we're
+ // computing address of stage2_end into r7.
+ add r7, r3, r5
+ bx r7
+
+blob_size:
+ .word stage2_end - stage2_start
+
+.align 4
+stage2_start:
+ .incbin "kernel_stage2.img"
+stage2_end:
+
+ // each word of the blob is loaded to r7 and stored
+ // from r7 to it's destination in a loop
+loop:
+ ldr r7, [r3, r6]
+ str r7, [r4, r6]
+ add r6, r6, #4
+ cmp r6, r5
+ blo loop
+
+ // Call stage2 of the kernel (branch to 0x0,
+ // which is the reset handler).
+ bx r4