voron

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

commit b846c0de864c0097beb0d99f5b2eb1fcbe01aab6
Author: oblique <psyberbits@gmail.com>
Date:   Wed Jun 20 20:57:54 +0300

initial stage

Diffstat:
Makefile | 41+++++++++++++++++++++++++++++++++++++++++
README | 1+
include/debug.h | 8++++++++
include/inttypes.h | 39+++++++++++++++++++++++++++++++++++++++
include/print.h | 11+++++++++++
include/rs232.h | 7+++++++
include/stddef.h | 6++++++
include/uart.h | 86+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
include/varg.h | 21+++++++++++++++++++++
kernel/debug.c | 25+++++++++++++++++++++++++
kernel/kmain.c | 6++++++
kernel/linker.ld | 20++++++++++++++++++++
kernel/print.c | 164+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
kernel/rs232.c | 30++++++++++++++++++++++++++++++
kernel/start.S | 6++++++
scripts/pandaboot.sh | 8++++++++
16 files changed, 479 insertions(+), 0 deletions(-)
diff --git a/Makefile b/Makefile @@ -0,0 +1,41 @@ +CROSS_COMPILE ?= arm-none-eabi- +MAKEFLAGS += -rR --no-print-directory +INC = -Iinclude +LDFLAGS = -T kernel/linker.ld +CFLAGS = -march=armv7-r -ggdb -Wall -Wextra -Wformat-security -Wshadow \ + -Wunreachable-code -Wpointer-arith -O2 -std=gnu99 -nostdlib \ + -nostdinc -nodefaultlibs -nostartfiles -fno-builtin $(INC) +ASFLAGS = -march=armv7-r -ggdb -nostdlib -nostdinc -nodefaultlibs \ + -nostartfiles -fno-builtin $(INC) +CC = $(CROSS_COMPILE)gcc +OBJCOPY = $(CROSS_COMPILE)objcopy +NM = $(CROSS_COMPILE)nm + +objs = kernel/start.o kernel/kmain.o kernel/rs232.o kernel/print.o \ + kernel/debug.o + +all: kernel.elf kernel.bin kernel.syms uImage + +kernel.elf: $(objs) kernel/linker.ld + @echo -e ' LD\t'$@ + @$(CC) $(LDFLAGS) -o $@ $(objs) + +kernel.bin: kernel.elf + @$(OBJCOPY) $< -O binary $@ + +kernel.syms: kernel.elf + @$(NM) $< > $@ + +uImage: kernel.bin + @mkimage -A arm -T kernel -C none -a 0x82000000 -e 0x82000000 -n Voron -d $< $@ + +%.o: %.c + @echo -e ' CC\t'$< + @$(CC) $(CFLAGS) -c -o $@ $< + +%.o: %.S + @echo -e ' AS\t'$< + @$(CC) $(ASFLAGS) -c -o $@ $< + +clean: + @rm -f $(objs) kernel.elf kernel.bin kernel.syms uImage diff --git a/README b/README @@ -0,0 +1 @@ +Voron is an experimental ARM based operating system. diff --git a/include/debug.h b/include/debug.h @@ -0,0 +1,8 @@ +#ifndef __DEBUG_H +#define __DEBUG_H + +void set_led_d1(int on); +void set_led_d2(int on); +void set_leds(int on); + +#endif /* __DEBUG_H */ diff --git a/include/inttypes.h b/include/inttypes.h @@ -0,0 +1,39 @@ +#ifndef __INTTYPES_H +#define __INTTYPES_H + +typedef signed char s8; +typedef unsigned char u8; +typedef short s16; +typedef unsigned short u16; +typedef int s32; +typedef unsigned int u32; +typedef long long s64; +typedef unsigned long long u64; + +typedef s8 int8_t; +typedef u8 uint8_t; +typedef s16 int16_t; +typedef u16 uint16_t; +typedef s32 int32_t; +typedef u32 uint32_t; +typedef s64 int64_t; +typedef u64 uint64_t; + +typedef unsigned int uint_t; +typedef unsigned long ulong_t; +typedef unsigned int size_t; +typedef int ssize_t; +typedef unsigned long uintptr_t; +typedef long intptr_t; + +#define S8_C(x) x +#define U8_C(x) x ## U +#define S16_C(x) x +#define U16_C(x) x ## U +#define S32_C(x) x +#define U32_C(x) x ## U +#define S64_C(x) x ## LL +#define U64_C(x) x ## ULL + + +#endif /* __INTTYPES_H */ diff --git a/include/print.h b/include/print.h @@ -0,0 +1,11 @@ +#ifndef __PRINT_H +#define __PRINT_H + +#include <varg.h> + +int kputs(const char *s); +int kputchar(int c); +int kprintf(const char *fmt, ...); +int kvprintf(const char *fmt, va_list ap); + +#endif /* __PRINT_H */ diff --git a/include/rs232.h b/include/rs232.h @@ -0,0 +1,7 @@ +#ifndef __RS232_H +#define __RS232_H + +int rs232_puts(const char *s); +int rs232_putchar(int c); + +#endif /* __RS232_H */ diff --git a/include/stddef.h b/include/stddef.h @@ -0,0 +1,6 @@ +#ifndef __STDDEF_H +#define __STDDEF_H + +#define NULL ((void*)0) + +#endif /* __STDDEF_H */ diff --git a/include/uart.h b/include/uart.h @@ -0,0 +1,86 @@ +#ifndef __UART_H +#define __UART_H + +#include <inttypes.h> + +/* TRM p.4459 */ +#define TX_FIFO_E (1<<5) + +/* TRM p.4444 */ +struct uart { + union { /* 0x00 */ + u32 thr; + const u32 rhr; + u32 dll; + }; + union { /* 0x04 */ + u32 ier; + u32 dlh; + }; + union { /* 0x08 */ + const u32 iir; + u32 fcr; + u32 efr; + }; + u32 lcr; /* 0x0c */ + union { /* 0x10 */ + u32 mcr; + u32 xon1_addr1; + }; + union { /* 0x14 */ + const u32 lsr; + u32 xon2_addr2; + }; + union { /* 0x18 */ + u32 tcr; + const u32 msr; + u32 xoff1; + }; + union { /* 0x1c */ + u32 spr; + u32 tlr; + u32 xoff2; + }; + u32 mdr1; /* 0x20 */ + u32 mdr2; /* 0x24 */ + union { /* 0x28 */ + const u32 sflsr; + u32 txfll; + }; + union { /* 0x2c */ + const u32 resume; + u32 txflh; + }; + union { /* 0x30 */ + const u32 sfregl; + u32 rxfll; + }; + union { /* 0x34 */ + const u32 sfregh; + u32 rxflh; + }; + union { /* 0x38 */ + u32 blr; + const u32 uasr; + }; + u32 acreg; /* 0x3c */ + u32 scr; /* 0x40 */ + const u32 ssr; /* 0x44 */ + u32 eblr; /* 0x48 */ + u32 __pad; /* 0x4c */ + const u32 mvr; /* 0x50 */ + u32 sysc; /* 0x54 */ + const u32 syss; /* 0x58 */ + u32 wer; /* 0x5c */ + u32 cfps; /* 0x60 */ + const u32 rxfifo_lvl; /* 0x64 */ + const u32 txfifo_lvl; /* 0x68 */ + u32 ier2; /* 0x6c */ + u32 isr2; /* 0x70 */ + u32 freq_sel; /* 0x74 */ + u32 __pad2[2]; /* 0x78 */ + u32 mdr3; /* 0x80 */ + u32 tx_dma_threshold; /* 0x84 */ +}; + +#endif /* __UART_H */ diff --git a/include/varg.h b/include/varg.h @@ -0,0 +1,21 @@ +#ifndef __VARG_H +#define __VARG_H + +#include <inttypes.h> + +#define _BND (sizeof(uintptr_t) - 1) +#define _bnd(X) ((sizeof(X) + _BND) & (~_BND)) + +/* AAPCS p.28 */ +struct __va_list { + char *__ap; +}; + +typedef struct __va_list va_list; + +#define va_start(ap, last) ((void) ((ap).__ap = ((char*) &(last) + _bnd(last)))) +#define va_end(ap) ((void) 0) +#define va_arg(ap, type) (*(type*) (((ap).__ap += _bnd(type)) - _bnd(type))) +#define va_copy(dest, src) ((void) ((dest).__ap = (src).__ap)) + +#endif /* __VARG_H */ diff --git a/kernel/debug.c b/kernel/debug.c @@ -0,0 +1,25 @@ +#include <inttypes.h> + +static volatile u32 *gpio_wk7 = (u32*)0x4A31E058; +static volatile u32 *gpio_wk8 = (u32*)0x4A31E05C; + +void set_led_d1(int on) { + u32 cur = *gpio_wk7 & 0xffff; + if (on) + *gpio_wk7 = cur | 0x001B0000; + else + *gpio_wk7 = cur | 0x00030000; +} + +void set_led_d2(int on) { + u32 cur = *gpio_wk8 & 0xffff0000; + if (on) + *gpio_wk8 = cur | 0x001B; + else + *gpio_wk8 = cur | 0x0003; +} + +void set_leds(int on) { + set_led_d1(on); + set_led_d2(on); +} diff --git a/kernel/kmain.c b/kernel/kmain.c @@ -0,0 +1,6 @@ +#include <print.h> +#include <debug.h> + +void kmain(void) { + kprintf("voron initial stage\n"); +} diff --git a/kernel/linker.ld b/kernel/linker.ld @@ -0,0 +1,20 @@ +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ + . = 0x82000000; + . = ALIGN(4); + .text : + { + kernel/start.o (.text) + *(.text) + } + + .data : { *(.data) } + + .bss : { *(.bss) } + + . = . + 0x2000; + _stack_top = .; +} diff --git a/kernel/print.c b/kernel/print.c @@ -0,0 +1,164 @@ +#include <inttypes.h> +#include <rs232.h> +#include <print.h> +#include <varg.h> + +int kputs(const char *s) { + return rs232_puts(s); +} + +int kputchar(int c) { + return rs232_putchar(c); +} + +static inline int abs(int n) { + if (n < 0) + return -n; + return n; +} + +static int print_int(int n) { + int ret = 0, i = 1; + + if (n > 0) { + while (n/i >= 10) + i *= 10; + } else if (n < 0) { + kputchar('-'); + ret++; + while (n/i <= -10) + i *= 10; + } + + while (i > 0) { + kputchar('0' + abs(n/i)); + ret++; + n -= (n/i)*i; + i /= 10; + } + + return ret; +} + +static int print_hexint(uint_t n) { + uint_t x, mask; + int i, bits, b, ret = 0; + + if (n == 0) { + kputchar('0'); + return 1; + } else { + bits = sizeof(uint_t) * 8; + b = bits; + mask = 0xf << (bits - 4); + + for (i = 1; i <= b/4; i++) { + if (n & mask) + break; + bits -= 4; + mask >>= 4; + } + + for (; i <= b/4; i++) { + bits -= 4; + x = (n & mask) >> bits; + mask >>= 4; + if (x < 0xa) + kputchar('0' + x); + else + kputchar('a' + x - 10); + ret++; + } + } + + return ret; +} + +static int print_pointer(uintptr_t p) { + uintptr_t x, mask; + int i, bits, b, ret = 0; + + if (p == 0) { + kputs("(nil)"); + return 5; + } else { + bits = sizeof(uintptr_t) * 8; + b = bits; + mask = 0xf << (bits - 4); + + kputs("0x"); + ret += 2; + + for (i = 1; i <= b/4; i++) { + bits -= 4; + x = (p & mask) >> bits; + mask >>= 4; + if (x < 0xa) + kputchar('0' + x); + else + kputchar('a' + x - 10); + ret++; + } + } + + return ret; +} + +int kprintf(const char *fmt, ...) { + va_list ap; + int ret; + + va_start(ap, fmt); + ret = kvprintf(fmt, ap); + va_end(ap); + + return ret; +} + +int kvprintf(const char *fmt, va_list ap) { + int d, ret = 0; + uint_t x; + uintptr_t p; + char c, *s; + + while (*fmt) { + switch (*fmt) { + case '%': + fmt++; + switch (*fmt) { + case 'd': + d = va_arg(ap, int); + ret += print_int(d); + break; + case 'x': + x = va_arg(ap, uint_t); + ret += print_hexint(x); + break; + case 'p': + p = va_arg(ap, uintptr_t); + ret += print_pointer(p); + break; + case 's': + s = va_arg(ap, char*); + ret += kputs(s); + break; + case 'c': + c = va_arg(ap, char); + kputchar(c); + ret++; + break; + case '%': + kputchar('%'); + ret++; + } + break; + default: + kputchar(*fmt); + ret++; + } + if (*fmt) + fmt++; + } + + return ret; +} diff --git a/kernel/rs232.c b/kernel/rs232.c @@ -0,0 +1,30 @@ +#include <inttypes.h> +#include <rs232.h> +#include <uart.h> + +static volatile struct uart *uart = (struct uart*)0x48020000; + +int rs232_puts(const char *s) { + int ret = 0; + + while (s[ret]) { + rs232_putchar(s[ret]); + ret++; + } + + return ret; +} + +int rs232_putchar(int c) { + if (c == '\n') { + while ((uart->lsr & TX_FIFO_E) == 0) + ; + uart->thr = (u32)'\r'; + } + /* while UART TX FIFO is not empty */ + while ((uart->lsr & TX_FIFO_E) == 0) + ; + /* write the character */ + uart->thr = (u32)c; + return c; +} diff --git a/kernel/start.S b/kernel/start.S @@ -0,0 +1,6 @@ +.text +.globl _start +_start: + ldr sp, =_stack_top + bl kmain + b . diff --git a/scripts/pandaboot.sh b/scripts/pandaboot.sh @@ -0,0 +1,8 @@ +#!/bin/sh +if [ $# -eq 0 ]; then + BIN="kernel.bin" +else + BIN=$1 +fi +USBBOOT_PATH="${HOME}/embedded/panda/omap4boot/out/panda" +sudo ${USBBOOT_PATH}/usbboot ${USBBOOT_PATH}/aboot.bin $BIN