commit 069f381c4c6cb4ffb994f2afaa53a5268c195372
parent 58c3a2e03394e9994de1111f7654c0a030fe24ed
Author: oblique <psyberbits@gmail.com>
Date: Tue, 10 Jul 2012 15:14:07 +0300
initialize interrupts stack, finish swi handler
Diffstat:
9 files changed, 145 insertions(+), 34 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -8,6 +8,5 @@
/kernel.elf
/kernel.syms
/uImage
-/usbbootImage.elf
/usbbootImage
/usbboot/kernel_image.ld
diff --git a/Makefile b/Makefile
@@ -14,12 +14,13 @@ OBJCOPY = $(CROSS_COMPILE)objcopy
NM = $(CROSS_COMPILE)nm
objs = kernel/start.o kernel/kmain.o kernel/rs232.o kernel/print.o \
- kernel/debug.o kernel/interrupts.o
+ kernel/debug.o kernel/interrupts.o kernel/syscall_table.o \
+ kernel/syscalls.o
all: kernel.elf kernel.bin kernel.syms uImage usbbootImage
kernel.elf: $(objs) kernel/linker.ld
- @echo -e ' LD\t'$@
+ @echo -e " LD\t$@"
@$(CC) $(LDFLAGS) -o $@ $(objs) $(LIBGCC)
kernel.bin: kernel.elf
@@ -31,27 +32,26 @@ kernel.syms: kernel.elf
uImage: kernel.bin
@mkimage -A arm -T kernel -C none -a 0x80008000 -e 0x80008000 -n Voron -d $< $@
-usbbootImage.elf: usbboot/usbboot.o usbboot/usbboot.ld usbboot/kernel_image.ld
- @echo -e ' LD\t'$@
- @$(CC) -T usbboot/usbboot.ld -nostdlib -nostdinc -nodefaultlibs -nostartfiles \
- -fno-builtin -o $@ $<
-
-usbbootImage: usbbootImage.elf
- @echo "Create usbbootImage"
+usbbootImage: usbboot/usbboot.o usbboot/usbboot.ld usbboot/kernel_image.ld
+ @echo "Creating $@"
@echo -e "Entry Point: 0x82000000"
- @$(OBJCOPY) $< -O binary $@
+ @$(CC) -T usbboot/usbboot.ld -nostdlib -nostdinc -nodefaultlibs -nostartfiles \
+ -fno-builtin -o __$@ $<
+ @$(OBJCOPY) __$@ -O binary $@
+ @rm -f __$@
+ @echo "Done"
usbboot/kernel_image.ld: kernel.bin
@hexdump -v -e '"BYTE(0x" 1/1 "%02X" ")\n"' $< > $@
%.o: %.c
- @echo -e ' CC\t'$<
+ @echo -e " CC\t$<"
@$(CC) $(CFLAGS) -c -o $@ $<
%.o: %.S
- @echo -e ' AS\t'$<
+ @echo -e " AS\t$<"
@$(CC) $(ASFLAGS) -c -o $@ $<
clean:
@rm -f $(objs) kernel.elf kernel.bin kernel.syms uImage usbbootImage \
- usbbootImage.elf usbboot/kernel_image.ld usbboot/usbboot.o
+ usbboot/kernel_image.ld usbboot/usbboot.o
diff --git a/include/p_modes.h b/include/p_modes.h
@@ -0,0 +1,12 @@
+#ifndef __P_MODES_H
+#define __P_MODES_H
+
+#define CPS_ABT 23
+#define CPS_FIQ 17
+#define CPS_IRQ 18
+#define CPS_SVC 19
+#define CPS_SYS 31
+#define CPS_UND 27
+#define CPS_USR 16
+
+#endif
diff --git a/kernel/interrupts.S b/kernel/interrupts.S
@@ -6,39 +6,72 @@ init_vector_table:
mcr p15, 0, r0, c1, c0, 0 @ write CP15 SCTRL register
ldr r0, =vector_table
- mcr p15, 0, r0, c12, c0, 0 @ set vector base address
+ mcr p15, 0, r0, c12, c0, 0 @ set vector base address (VBAR)
bx lr
+.balign 32 @ the 5 least-significant bits of VBAR are reserved (i.e. 32 bytes alignment)
vector_table:
ldr pc, =reset
- ldr pc, =undefined
- ldr pc, =svc
+ ldr pc, =undefined_insn
+ ldr pc, =swi_ex
ldr pc, =prefetch_abort
ldr pc, =data_abort
- mov pc, lr
- ldr pc, =irq
- ldr pc, =fiq
+ b . @ not assigned
+ ldr pc, =irq_ex
+ ldr pc, =fiq_ex
.ltorg
reset:
b .
-undefined:
- b .
+undefined_insn:
+ movs pc, lr
+
+
+/* system call number is the swi number
+ * if system call takes less than 7 arguments
+ * we use r0 until r5 from userland to pass them
+ * if it takes more than 6 arguments we pass a
+ * pointer of the arguments at r0
+ */
+swi_ex:
+ stmfd sp!, { r6 - r12, lr }
+ mrs r6, spsr
+ stmfd sp!, { r6 }
+
+ ldr r6, [lr, #-4]
+ bic r6, r6, #0xff000000
+
+ stmfd sp!, { r4, r5 }
+ ldr lr, =.Lsyscall_ret
+ ldr r7, =syscall_table
+ ldr pc, [r7, r6, lsl #2]
+
+.Lsyscall_ret:
+ add sp, sp, #8
+ ldmfd sp!, { r6 }
+ msr spsr, r6
+ ldmfd sp!, { r6 - r12, pc }^
-svc:
- b .
prefetch_abort:
- b .
+ subs pc, lr, #4
data_abort:
- b .
+ subs pc, lr, #8
-irq:
- b .
+irq_ex:
+ sub lr, lr, #4
+ stmfd sp!, { lr }
+ mov r0, #1
+ bl set_led_d1
+ ldmfd sp!, { pc }^
-fiq:
- b .
+fiq_ex:
+ sub lr, lr, #4
+ stmfd sp!, { lr }
+ mov r0, #1
+ bl set_led_d2
+ ldmfd sp!, { pc }^
diff --git a/kernel/linker.ld b/kernel/linker.ld
@@ -3,6 +3,8 @@ OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
+ _usr_stack_top = 0x80000000;
+
.text 0x80008000 :
{
kernel/start.o (.text)
@@ -24,5 +26,7 @@ SECTIONS
*(.bss)
}
- _stack_top = . + 0x2000;
+ _svc_stack_top = . + 0x2000;
+ _fiq_stack_top = . + 0x2000;
+ _irq_stack_top = . + 0x2000;
}
diff --git a/kernel/start.S b/kernel/start.S
@@ -1,8 +1,10 @@
+#include <p_modes.h>
+
.section .text
.globl _start
_start:
cpsid if @ disable interrupts
- ldr sp, =_stack_top @ set stack
+ ldr sp, =_svc_stack_top @ set SVC stack
/* set leds off */
mov r0, #0
@@ -15,6 +17,38 @@ _start:
/* initialize vector table */
bl init_vector_table
+ cps #CPS_FIQ @ change to FIQ mode
+ ldr sp, =_fiq_stack_top @ set FIQ stack
+
+ cps #CPS_IRQ @ change to IRQ mode
+ ldr sp, =_irq_stack_top @ set IRQ stack
+
+ cps #CPS_SVC @ change to SVC mode
+ cpsie if @ enable interrupts
+
+ /* example of calling a system call with at least 6 arguments */
+ mov r0, #1
+ mov r1, #2
+ mov r2, #3
+ mov r3, #4
+ mov r4, #5
+ mov r5, #6
+ swi #0
+
+ /* example of calling a system call with more than 6 arguments */
+ mov r0, #7
+ stmfd sp!, { r0 }
+ mov r0, #1
+ mov r1, #2
+ mov r2, #3
+ mov r3, #4
+ mov r4, #5
+ mov r5, #6
+ stmfd sp!, { r0 - r5 }
+ mov r0, sp
+ swi #1
+ add sp, sp, #(7 * 4)
+
bl kmain
b .
diff --git a/kernel/syscall_table.S b/kernel/syscall_table.S
@@ -0,0 +1,5 @@
+.section .text
+.globl syscall_table
+syscall_table:
+ .word sys_test_6_args
+ .word sys_test_7_args
diff --git a/kernel/syscalls.c b/kernel/syscalls.c
@@ -0,0 +1,24 @@
+#include <print.h>
+#include <inttypes.h>
+
+long sys_test_6_args(u32 a1, u32 a2, u32 a3, u32 a4, u32 a5, u32 a6) {
+ kprintf("sys_test_6_args(%d, %d, %d, %d, %d, %d)\n", a1, a2, a3, a4, a5, a6);
+ return 0;
+}
+
+
+struct __test_7_args {
+ u32 a1;
+ u32 a2;
+ u32 a3;
+ u32 a4;
+ u32 a5;
+ u32 a6;
+ u32 a7;
+};
+
+long sys_test_7_args(struct __test_7_args *a) {
+ kprintf("sys_test_7_args(%d, %d, %d, %d, %d, %d, %d)\n",
+ a->a1, a->a2, a->a3, a->a4, a->a5, a->a6, a->a7);
+ return 0;
+}
diff --git a/usbboot/usbboot.S b/usbboot/usbboot.S
@@ -2,7 +2,7 @@
.globl _start
_start:
ldr sp, =_usbboot_stack_top
- push { r0 - r12 }
+ stmfd sp!, { r0 - r12 }
/* copy kernel image at 0x80008000 */
ldr r0, =_image_start
@@ -15,5 +15,5 @@ _start:
cmp r0, r1
blo .L1
- pop { r0 - r12 }
+ ldmfd sp!, { r0 - r12 }
ldr pc, =0x80008000 @ jump to 0x80008000