voron

experimental ARM OS
git clone git://git.2f30.org/voron
Log | Files | Refs | README | LICENSE

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:
M.gitignore | 1-
MMakefile | 26+++++++++++++-------------
Ainclude/p_modes.h | 12++++++++++++
Mkernel/interrupts.S | 65+++++++++++++++++++++++++++++++++++++++++++++++++----------------
Mkernel/linker.ld | 6+++++-
Mkernel/start.S | 36+++++++++++++++++++++++++++++++++++-
Akernel/syscall_table.S | 5+++++
Akernel/syscalls.c | 24++++++++++++++++++++++++
Musbboot/usbboot.S | 4++--
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