summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas White <taw@physics.org>2018-06-19 21:53:09 +0200
committerThomas White <taw@physics.org>2018-06-19 22:42:21 +0200
commit420e355173ca5c4c6f26ac19b1f5ab20e1723a7a (patch)
tree7a300a0c2da3b216ebd72a6304f2587e21645986
Initial commit
-rw-r--r--Makefile13
-rw-r--r--linkscript.ld8
-rw-r--r--src/main.s132
3 files changed, 153 insertions, 0 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..aeac4a4
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,13 @@
+all: kernel.img
+
+kernel.img: kernel.elf
+ arm-linux-gnu-objcopy kernel.elf -O binary kernel.img
+
+kernel.elf : main.o linkscript.ld
+ arm-linux-gnu-ld --no-undefined main.o -o kernel.elf -T linkscript.ld
+
+main.o: src/main.s
+ arm-linux-gnu-as -Isrc src/main.s -o main.o
+
+clean:
+ rm -f main.o kernel.elf kernel.img
diff --git a/linkscript.ld b/linkscript.ld
new file mode 100644
index 0000000..897ef57
--- /dev/null
+++ b/linkscript.ld
@@ -0,0 +1,8 @@
+SECTIONS {
+ .init 0x8000 : { *(.init) }
+ . = ALIGN(0x1000);
+ . = . + 0x800;
+ stack_svc = .;
+ . = . + 0x800;
+ stack_usr = .;
+}
diff --git a/src/main.s b/src/main.s
new file mode 100644
index 0000000..e45da64
--- /dev/null
+++ b/src/main.s
@@ -0,0 +1,132 @@
+@ Tiny bare metal example
+@ vim:ft=armv5
+
+.section .init
+
+_start:
+ LDR PC, [PC, #24] @ Reset
+ LDR PC, [PC, #24] @ Undefined
+ LDR PC, [PC, #24] @ SWI
+ LDR PC, [PC, #24] @ Prefetch abort
+ LDR PC, [PC, #24] @ Data abort
+ LDR PC, [PC, #24] @ Reserved
+ LDR PC, [PC, #24] @ IRQ
+ LDR PC, [PC, #24] @ FIQ
+ .word reset @ Reset
+ .word hang @ Undefined
+ .word swi_handler @ SWI
+ .word hang @ Prefetch abort
+ .word hang @ Data abort
+ .word hang @ Reserved
+ .word hang @ IRQ
+ .word hang @ FIQ
+
+hang:
+ B hang
+
+reset:
+
+ @ Hang all except one of the processors
+ MRC P15, 0, R0, C0, C0, 5
+ AND R0, R0, #3
+ CMP R0, #0
+ BNE hang
+
+ @ Get out of HYP mode
+ MRS R0, CPSR
+ BIC R0, R0, #0x1f
+ ORR R0, R0, #0x13
+ MSR SPSR_cxsf, R0
+ ADD R0, PC, #4
+ MSR ELR_hyp,r0
+ ERET
+
+ LDR R13, =stack_svc @ Set up stack for SVC mode
+
+ @ Relocate vector table
+ MOV R10, #0x8000
+ MOV R11, #0
+ LDMIA R10!, {R0-R7}
+ STMIA R11!, {R0-R7}
+ LDMIA R10!, {R0-R7}
+ STMIA R11!, {R0-R7}
+
+ LDR R8, =0x3f200000
+ LDR R1, [R8, #0x04] @ GPFSEL1
+ ORR R1, R1, #1<<18 @ GPIO pin 16 is output
+ BIC R1, R1, #3<<21 @ GPIO pin 17 is input
+ ORR R1, R1, #1<<24 @ GPIO pin 18 is output
+ STR R1, [R8, #0x04] @ GPFSEL1
+
+ @ Flash green LED
+ MOV R1, #1<<18
+ STR R1, [R8, #0x1c] @ GPSET0
+ BL pause
+ MOV R1, #1<<18
+ STR R1, [R8, #0x28] @ GPCLR0
+ BL pause
+
+ @ Switch to USR mode and set up stack
+ MRS R0, CPSR
+ BIC R0, R0, #0x1f
+ ORR R0, R0, #0x10
+ MSR CPSR_c, R0
+ LDR R13, =stack_usr
+
+repeat:
+ MOV R0, #0
+ SWI 0
+ TST R0, #1<<17
+ MOVNE R0, #1
+ SWINE 0
+ B repeat
+
+
+swi_handler:
+ STMDB R13!, {R8, LR}
+ LDR R8, =0x3f200000
+ CMP R0, #0
+ BEQ get_gpio
+ CMP R0, #1
+ BLEQ flash
+ LDMIA R13!, {R8, PC}^
+
+get_gpio:
+ LDR R0, [R8, #0x34] @ GPLEV0
+ LDMIA R13!, {R8, PC}^
+
+
+flash:
+ STMDB R13!, {R1, R2, R4, LR}
+ MOV R4, #5
+
+flashloop:
+ MOV R1, #1<<16
+ STR R1, [R8, #0x28] @ GPCLR0
+ MOV R1, #1<<18
+ STR R1, [R8, #0x1c] @ GPSET0
+
+ BL pause
+
+ MOV R1, #1<<18
+ STR R1, [R8, #0x28] @ GPCLR0
+ MOV R1, #1<<16
+ STR R1, [R8, #0x1c] @ GPSET0
+
+ BL pause
+
+ MOV R1, #1<<18
+ ORR R1, #1<<16
+ STR R1, [R8, #0x28] @ GPCLR0
+
+ SUBS R4, R4, #1
+ BNE flashloop
+
+ LDMIA R13!, {R1, R2, R4, PC}
+
+pause:
+ MOV R2, #0x3f000
+wait:
+ SUBS R2, R2, #1
+ BNE wait
+ MOV PC, LR