aboutsummaryrefslogtreecommitdiff
path: root/kernel_stage1.S
diff options
context:
space:
mode:
authorvetch <vetch97@gmail.com>2020-01-04 19:37:32 +0100
committervetch <vetch97@gmail.com>2020-01-04 19:37:32 +0100
commit615e3302c9dd358bb64cd56d1f3814ad8d5df84d (patch)
tree07b0469807eb3bff7ff7d3f3576858642bc66675 /kernel_stage1.S
parent885a097da42317f48cead2d91c0e0240066943a8 (diff)
downloadrpi-MMU-example-615e3302c9dd358bb64cd56d1f3814ad8d5df84d.tar.gz
rpi-MMU-example-615e3302c9dd358bb64cd56d1f3814ad8d5df84d.zip
rearranged files, updated makefile
Diffstat (limited to 'kernel_stage1.S')
-rw-r--r--kernel_stage1.S168
1 files changed, 0 insertions, 168 deletions
diff --git a/kernel_stage1.S b/kernel_stage1.S
deleted file mode 100644
index dd3e6fd..0000000
--- a/kernel_stage1.S
+++ /dev/null
@@ -1,168 +0,0 @@
-/* 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
-
- // we'll use the size of stage1 to determine where we have free
- // space after it. We'll then copy our atags/fdt there, so
- // it doesn't get overwritten by stage2 we deploy at 0x0
-atags_magic:
- .word 0x54410001
-
-proceed:
- // load the second word of structure passed to us through r2;
- // if it's atags, it's second word should be the magic number
- // Btw, location of ATAGS is always 0x100.
- ldr r3, [r2, #4]
- adr r4, atags_magic
- ldr r4, [r4]
-
- // compare second word of assumed atags with magic number
- // to see, if it's really atags and not sth else (i.e. fdt)
- cmp r3, r4
-
- // normally at start r0 contains value 0;
- // value 3 in r0 would tell stage2 code, we found no atags :(
- movne r0, #3
- bne stage2_blob_copying
-
- // if atags was found, copying of it takes place here
-
- // the following loop finds, where atags ends
- // r3 shall point to currently looked-at tag
- mov r3, r2
-
-find_end_of_atags_loop:
- // load first word of tag header to r4 (it contains tag size)
- ldr r4, [r3]
- // make r3 point at the next tag (by adding 4*tag_size to it)
- add r3, r4, lsl #2
-
- // load second word of tag header to r5 (it contains tag type)
- ldr r5, [r3, #4]
-
- // if tag value is 0, it is the last tag
- cmp r5, #0
- bne find_end_of_atags_loop
-
- add r3, #8 // make r3 point at the end of last tag
- sub r3, r2 // get atags size in r3
-
- // at this pont r2 and r3 point at start and size of atags,
- // respectively; now we'll compute, where we're going to have
- // free space to put atags in; we want to put atags either
- // right after our blob or, if if it doesn't fit between
- // blob end and the address stage1 is loaded at, after stage1
-
- // get blob size to r5
- adr r5, blob_size
- ldr r5, [r5]
-
- // we could only copy atags to a 4-aligned address
- mov r6, #4
- bl aling_r5_to_r6
-
- // compute where atags copied right after blob would end
- add r6, r5, r3
- // we can only overwrite stuff before the copying loop
- adr r7, copy_atags_loop
- cmp r6, r7
- ble copy_atags
-
- // atags wouldn't fit - use memory after stage1 as destination
- adr r5, _boot
- adr r6, stage1_size
- ldr r6, [r6]
- add r5, r6
- mov r6, #4
- bl aling_r5_to_r6
-
-copy_atags:
- // now copy atags (r2 - atags start; r3 - atags size;
- // r5 - destination; r4 - iterator; r6 - buffor)
- mov r4, #0
-
-copy_atags_loop:
- ldr r6, [r2, r4]
- str r6, [r5, r4]
- add r4, #4
- cmp r4, r3
- blo copy_atags_loop
-
- mov r2, r5 // place the new atags address in r2
- b stage2_blob_copying // atags stuff done; proceed
-
-// mini-function, that does what the label says; clobbers r7
-aling_r5_to_r6:
- sub r5, #1
- sub r7, r6, #1
- bic r5, r7
- add r5, r6
- mov pc, lr
-
-
-stage2_blob_copying: // 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
-stage1_size:
- .word stage1_end - _boot
-
-.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
-
-stage1_end: