diff options
author | Richard Braun <rbraun@sceen.net> | 2017-10-04 00:47:53 +0200 |
---|---|---|
committer | Richard Braun <rbraun@sceen.net> | 2017-10-04 00:47:53 +0200 |
commit | 2f26df6d916daf1d4dbba9b2a91e7fe237329534 (patch) | |
tree | 97fece93a97149c778d4e297b8b0e014a41a827f | |
parent | 94b7a411a2aacc75ef823c15ffad52cbbabab738 (diff) |
Hello, world!
-rw-r--r-- | arch/arm/Makefile | 2 | ||||
-rw-r--r-- | arch/arm/machine/asm.h | 42 | ||||
-rw-r--r-- | arch/arm/machine/boot.c | 33 | ||||
-rw-r--r-- | arch/arm/machine/boot.h | 21 | ||||
-rw-r--r-- | arch/arm/machine/boot_asm.S | 65 | ||||
-rw-r--r-- | arch/arm/machine/cpu.h | 17 | ||||
-rw-r--r-- | arch/arm/machine/pmap.h | 2 | ||||
-rw-r--r-- | arch/arm/machine/tcb_asm.S | 21 | ||||
-rw-r--r-- | arch/arm/x15.lds.S | 33 | ||||
-rw-r--r-- | arch/x86/machine/asm.h | 8 |
10 files changed, 215 insertions, 29 deletions
diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 7c74a409..84214f0a 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -1,6 +1,7 @@ KCONFIG_DEFCONFIG := qemu_virt_defconfig XBUILD_CFLAGS += -mcpu=cortex-a15 +XBUILD_CFLAGS += -fdelete-null-pointer-checks x15_SOURCES-y += \ arch/arm/machine/boot_asm.S \ @@ -8,4 +9,5 @@ x15_SOURCES-y += \ arch/arm/machine/cpu.c \ arch/arm/machine/pmap.c \ arch/arm/machine/strace.c \ + arch/arm/machine/tcb_asm.S \ arch/arm/machine/tcb.c diff --git a/arch/arm/machine/asm.h b/arch/arm/machine/asm.h new file mode 100644 index 00000000..6474b225 --- /dev/null +++ b/arch/arm/machine/asm.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2011, 2012 Richard Braun. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef _X86_ASM_H +#define _X86_ASM_H + +#ifndef __ASSEMBLER__ +#warning "asm.h included from a C file" +#endif /* __ASSEMBLER__ */ + +#include <machine/cpu.h> + +#define ASM_FUNC(x) \ +.align CPU_TEXT_SHIFT; \ +.global x; \ +.type x, STT_FUNC; \ +x + +#define ASM_DATA(x) \ +.align CPU_DATA_SHIFT; \ +.global x; \ +.type x, STT_OBJECT; \ +x + +#define ASM_END(x) \ +.size x, . - x + +#endif /* _X86_ASM_H */ diff --git a/arch/arm/machine/boot.c b/arch/arm/machine/boot.c index 121ad92a..eb054f66 100644 --- a/arch/arm/machine/boot.c +++ b/arch/arm/machine/boot.c @@ -15,8 +15,41 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include <stdalign.h> +#include <stddef.h> +#include <stdint.h> + #include <kern/init.h> #include <machine/boot.h> +#include <machine/cpu.h> +#include <machine/pmap.h> +#include <vm/vm_kmem.h> + +alignas(CPU_DATA_ALIGN) char boot_stack[BOOT_STACK_SIZE] __bootdata; + +static char boot_hello_msg[] __bootdata = "Hello, world!\r\n"; + +static void __boot +boot_hello_world(void) +{ + volatile unsigned long *uart_data_reg = (volatile unsigned long *)0x9000000; + const char *s = boot_hello_msg; + + while (*s != '\0') { + *uart_data_reg = *s; + s++; + } +} + +void boot_setup_paging(void); + +void __boot +boot_setup_paging(void) +{ + boot_hello_world(); + + for (;;); +} void __init boot_log_info(void) diff --git a/arch/arm/machine/boot.h b/arch/arm/machine/boot.h index 6459e80b..0181f7a0 100644 --- a/arch/arm/machine/boot.h +++ b/arch/arm/machine/boot.h @@ -19,16 +19,33 @@ #define _ARM_BOOT_H #include <kern/macros.h> +#include <machine/page.h> #include <machine/pmap.h> -#define BOOT_OFFSET DECL_CONST(0x0, UL) +/* + * Size of the stack used when booting a processor. + */ +#define BOOT_STACK_SIZE PAGE_SIZE + +#define BOOT_LOAD_SECTION .boot.load +#define BOOT_TEXT_SECTION .boot.text +#define BOOT_DATA_SECTION .boot.data -#define BOOT_VTOP(addr) ((addr) - PMAP_KERNEL_OFFSET) +#define BOOT_RAM_START 0x40000000 /* XXX Specific to the Qemu virtual machine */ +#define BOOT_KERNEL_OFFSET (PMAP_START_KERNEL_ADDRESS - BOOT_RAM_START) + +#define BOOT_RTOL(addr) ((addr) - BOOT_RAM_START) +#define BOOT_VTOL(addr) ((addr) - PMAP_START_KERNEL_ADDRESS) + +#define BOOT_VTOP(addr) ((addr) - BOOT_RAM_START) #ifndef __ASSEMBLER__ #include <kern/init.h> +#define __boot __section(QUOTE(BOOT_TEXT_SECTION)) +#define __bootdata __section(QUOTE(BOOT_DATA_SECTION)) __attribute__((used)) + /* * Log kernel version and other architecture-specific information. */ diff --git a/arch/arm/machine/boot_asm.S b/arch/arm/machine/boot_asm.S index ccf3eb05..fedb63bb 100644 --- a/arch/arm/machine/boot_asm.S +++ b/arch/arm/machine/boot_asm.S @@ -15,11 +15,64 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -.section .boot.hdr, "awx" +#include <machine/asm.h> +#include <machine/boot.h> +#include <machine/pmap.h> -.long _start +.section BOOT_LOAD_SECTION, "awx" -.global _start -_start: - mov %r0, #0x12 - b . +ASM_DATA(boot_exception_table): + .long _start /* Reset */ + .long 0 /* Undefined instruction */ + .long 0 /* Software interrupt */ + .long 0 /* Prefetch abort */ + .long 0 /* Data abort */ + .long 0 /* IRQ */ + .long 0 /* FIQ */ +ASM_END(boot_exception_table) + +ASM_FUNC(_start): + /* + * Assume the code runs from flash. For the sake of simplicity, make + * the kernel run from RAM. This requires relocating it, and since the + * RAM size isn't known, we can't use it for a stack. As a result, + * perform the relocation in assembly without using a stack. + */ + ldr %r5, =(BOOT_RAM_START) /* Load RAM address in %r5 */ + mov %r6, #0 /* Load kernel address in %r6 */ + ldr %r0, boot_kernel_end /* Load kernel end virtual address + in %r0 */ + ldr %r1, =(PMAP_START_KERNEL_ADDRESS) /* Load kernel virtual address in %r1 */ + sub %r7, %r0, %r1 /* Compute kernel size in bytes */ + lsr %r7, %r7, #2 /* Compute kernel size in words */ + + sub %r5, %r5, #4 /* Prepare for auto-increment */ + sub %r6, %r6, #4 + +1: + ldr %r0, [%r6, #4]! /* Load word with auto-increment */ + str %r0, [%r5, #4]! /* Store word with auto-increment */ + sub %r7, %r7, #4 /* Account for the written word */ + cmp %r7, #0 /* Check the number of words left */ + beq 1f /* Break if copy complete */ + b 1b /* Continue otherwise */ + +1: + /* TODO Invalidate all caches */ + + /* Set up the stack */ + ldr %r13, boot_stack_addr + add %r13, %r13, #BOOT_STACK_SIZE + + bl boot_setup_paging + + /* Never reached */ + nop + +ASM_END(_start) + +boot_kernel_end: + .long _end + +boot_stack_addr: + .long boot_stack diff --git a/arch/arm/machine/cpu.h b/arch/arm/machine/cpu.h index 80e11a05..d8b4c4d1 100644 --- a/arch/arm/machine/cpu.h +++ b/arch/arm/machine/cpu.h @@ -29,8 +29,23 @@ /* * Data alignment, normally the word size. + * + * TODO Check. + */ +#define CPU_DATA_SHIFT 2 +#define CPU_DATA_ALIGN (1 << CPU_DATA_SHIFT) + +/* + * Function alignment. + * + * Aligning functions improves instruction fetching. + * + * Used for assembly functions only. + * + * XXX Use this value until processor selection is available. */ -#define CPU_DATA_ALIGN (LONG_BIT / 8) +#define CPU_TEXT_SHIFT 4 +#define CPU_TEXT_ALIGN (1 << CPU_TEXT_SHIFT) #ifndef __ASSEMBLER__ diff --git a/arch/arm/machine/pmap.h b/arch/arm/machine/pmap.h index bae0c060..ecb3bf16 100644 --- a/arch/arm/machine/pmap.h +++ b/arch/arm/machine/pmap.h @@ -29,8 +29,6 @@ #define PMAP_START_DIRECTMAP_ADDRESS PMAP_END_ADDRESS #define PMAP_END_DIRECTMAP_ADDRESS DECL_CONST(0xf8000000, UL) -#define PMAP_KERNEL_OFFSET PMAP_START_DIRECTMAP_ADDRESS - #define PMAP_START_KMEM_ADDRESS PMAP_END_DIRECTMAP_ADDRESS #define PMAP_END_KMEM_ADDRESS PMAP_END_KERNEL_ADDRESS diff --git a/arch/arm/machine/tcb_asm.S b/arch/arm/machine/tcb_asm.S new file mode 100644 index 00000000..f58f429e --- /dev/null +++ b/arch/arm/machine/tcb_asm.S @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2017 Richard Braun. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <machine/asm.h> + +ASM_FUNC(tcb_load): +ASM_END(tcb_load) diff --git a/arch/arm/x15.lds.S b/arch/arm/x15.lds.S index a5c6cd3b..d867de29 100644 --- a/arch/arm/x15.lds.S +++ b/arch/arm/x15.lds.S @@ -7,11 +7,11 @@ ENTRY(_start) #include <machine/boot.h> #include <machine/cpu.h> #include <machine/page.h> -#include <machine/pmap.h> PHDRS { /* Flags are actually similar to classic Unix permissions */ + load PT_LOAD FLAGS(7); boot PT_LOAD FLAGS(7); init PT_LOAD FLAGS(7); percpu PT_LOAD FLAGS(6); @@ -22,22 +22,27 @@ PHDRS SECTIONS { - . = BOOT_OFFSET; + . = 0; + + .boot.load : { + *(BOOT_LOAD_SECTION) + } : load + + . += BOOT_RAM_START; _boot = .; - .boot ALIGN(PAGE_SIZE) : { - *(.boot.hdr) - *(.boot.text) - *(.boot.data) + .boot ALIGN(PAGE_SIZE) : AT(BOOT_RTOL(ADDR(.boot))) { + *(BOOT_TEXT_SECTION) + *(BOOT_DATA_SECTION) } : boot . = ALIGN(PAGE_SIZE); _boot_end = .; - . += PMAP_KERNEL_OFFSET; + . += (PMAP_START_KERNEL_ADDRESS - BOOT_RAM_START); _init = .; - .init ALIGN(PAGE_SIZE) : AT(BOOT_VTOP(ADDR(.init))) { + .init ALIGN(PAGE_SIZE) : AT(BOOT_VTOL(ADDR(.init))) { *(.init.text) *(.init.data) @@ -52,7 +57,7 @@ SECTIONS _init_end = .; _percpu = .; - .percpu 0 : AT(BOOT_VTOP(_percpu)) { + .percpu 0 : AT(BOOT_VTOL(_percpu)) { *(.percpu) } : percpu @@ -61,32 +66,32 @@ SECTIONS _percpu_end = .; _text = .; - .text ALIGN(PAGE_SIZE) : AT(BOOT_VTOP(ADDR(.text))) { + .text ALIGN(PAGE_SIZE) : AT(BOOT_VTOL(ADDR(.text))) { *(.text) } : text . = ALIGN(PAGE_SIZE); _rodata = .; - .rodata ALIGN(PAGE_SIZE) : AT(BOOT_VTOP(ADDR(.rodata))) { + .rodata ALIGN(PAGE_SIZE) : AT(BOOT_VTOL(ADDR(.rodata))) { *(.rodata) } : rodata - .notes ALIGN(CPU_DATA_ALIGN) : AT(BOOT_VTOP(ADDR(.notes))) { + .notes ALIGN(CPU_DATA_ALIGN) : AT(BOOT_VTOL(ADDR(.notes))) { *(.note.*) } : rodata . = ALIGN(PAGE_SIZE); _data = .; - .data ALIGN(PAGE_SIZE) : AT(BOOT_VTOP(ADDR(.data))) { + .data ALIGN(PAGE_SIZE) : AT(BOOT_VTOL(ADDR(.data))) { . = ALIGN(CPU_L1_SIZE); *(.data.read_mostly) . = ALIGN(CPU_L1_SIZE); *(.data) } : data - .bss ALIGN(CPU_DATA_ALIGN) : AT(BOOT_VTOP(ADDR(.bss))) { + .bss ALIGN(CPU_DATA_ALIGN) : AT(BOOT_VTOL(ADDR(.bss))) { *(.bss) } : data diff --git a/arch/x86/machine/asm.h b/arch/x86/machine/asm.h index 204d6fed..754c8f2f 100644 --- a/arch/x86/machine/asm.h +++ b/arch/x86/machine/asm.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012 Richard Braun. + * Copyright (c) 2011-2012 Richard Braun. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,8 +15,8 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef _X86_ASM_H -#define _X86_ASM_H +#ifndef _ARM_ASM_H +#define _ARM_ASM_H #ifndef __ASSEMBLER__ #warning "asm.h included from a C file" @@ -39,4 +39,4 @@ x: #define ASM_END(x) \ .size x, . - x -#endif /* _X86_ASM_H */ +#endif /* _ARM_ASM_H */ |