commit e6669b6ab2d027b1f21a416737d26d5788764888
parent 6ef96df11b3aa0a5367df9be0fcb1dc02f94a277
Author: oblique <psyberbits@gmail.com>
Date: Sun, 9 Sep 2012 23:27:08 +0300
added: spinlock, simple heap allocator, gcc constructors support, linked lists
Diffstat:
21 files changed, 495 insertions(+), 37 deletions(-)
diff --git a/Makefile b/Makefile
@@ -14,15 +14,17 @@ LD = $(CROSS_COMPILE)ld
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/syscall_table.o \
- kernel/syscalls.o kernel/mmu.o kernel/mm.o
+KERNEL_SRCS_C = $(wildcard kernel/*.c)
+KERNEL_SRCS_S = $(wildcard kernel/*.S)
+KERNEL_SRCS = $(KERNEL_SRCS_C) $(KERNEL_SRCS_S)
+KERNEL_OBJS = $(KERNEL_SRCS_C:%.c=%.o) $(KERNEL_SRCS_S:%.S=%.o)
+HDRS = $(wildcard include/*.h)
all: uImage usbbootImage kernel.syms
-kernel.elf: $(objs) kernel/linker.ld
+kernel.elf: $(KERNEL_OBJS) kernel/linker.ld
@echo -e " LD\t$@"
- @$(CC) $(LDFLAGS) -o $@ $(objs) $(LIBGCC)
+ @$(CC) $(LDFLAGS) -o $@ $(KERNEL_OBJS) $(LIBGCC)
kernel.bin: kernel.elf
@$(OBJCOPY) $< -O binary $@
@@ -46,16 +48,16 @@ usbbootImage: usbboot/usbboot.o usbboot/usbboot.ld usbboot/kernel_image.o
usbboot/kernel_image.o: kernel.bin
@$(LD) -r -b binary -o $@ $<
-%.o: %.c
+%.o: %.c $(HDRS)
@echo -e " CC\t$<"
@$(CC) $(CFLAGS) -c -o $@ $<
-%.o: %.S
+%.o: %.S $(HDRS)
@echo -e " AS\t$<"
@$(CC) $(ASFLAGS) -c -o $@ $<
clean:
- @rm -f $(objs) kernel.elf kernel.bin kernel.syms uImage usbbootImage \
+ @rm -f $(KERNEL_OBJS) kernel.elf kernel.bin kernel.syms uImage usbbootImage \
usbboot/kernel_image.o usbboot/usbboot.o voron.tar.gz
targz:
diff --git a/include/alloc.h b/include/alloc.h
@@ -0,0 +1,10 @@
+#ifndef __ALLOC_H
+#define __ALLOC_H
+
+#include <inttypes.h>
+
+void *kmalloc(size_t size);
+void kfree(void *addr);
+void kdump();
+
+#endif /* __ALLOC_H */
diff --git a/include/errno.h b/include/errno.h
@@ -36,4 +36,10 @@
#define EDOM 33 /* Math argument out of domain of func */
#define ERANGE 34 /* Math result not representable */
+#define MAX_ERRNO 34
+#define IS_ERR(x) ((unsigned long)(x) >= (unsigned long)-MAX_ERRNO)
+#define PTR_ERR(x) ((unsigned long)(x))
+#define ERR_PTR(x) ((void*)(x))
+
+
#endif /* __ERRNO_H */
diff --git a/include/kernel.h b/include/kernel.h
@@ -0,0 +1,18 @@
+#ifndef __KERNEL_H
+#define __KERNEL_H
+
+#include <inttypes.h>
+#include <stddef.h>
+#include <print.h>
+#include <io.h>
+#include <errno.h>
+#include <varg.h>
+
+#define container_of(ptr, type, member) ({ \
+ const typeof(((type*)0)->member) *__mptr = (ptr); \
+ (type*)((uintptr_t)__mptr - offsetof(type, member)); \
+})
+
+#define ARRAY_SIZE(arr) (sizeof(arr)/sizeof(arr[0]))
+
+#endif /* __KERNEL_H */
diff --git a/include/list.h b/include/list.h
@@ -0,0 +1,67 @@
+#ifndef __LIST_H
+#define __LIST_H
+
+#include <kernel.h>
+
+struct list_head {
+ struct list_head *prev;
+ struct list_head *next;
+};
+
+#define LIST_HEAD_INIT(name) { &(name), &(name) }
+#define LIST_HEAD(name) struct list_head name = LIST_HEAD_INIT(name)
+
+#define list_entry(ptr, type, member) container_of(ptr, type, member)
+
+/* list_for_each - iterate over a list
+ * pos: the &struct list_head to use as a loop cursor.
+ * head: the head for your list.
+ */
+#define list_for_each(pos, head) \
+ for (pos = (head)->next; pos != (head); \
+ pos = pos->next)
+
+/* list_for_each_safe - iterate over a list safe against removal of list entry
+ * pos: the &struct list_head to use as a loop cursor.
+ * n: another &struct list_head to use as temporary storage
+ * head: the head for your list.
+ */
+#define list_for_each_safe(pos, n, head) \
+ for (pos = (head)->next, n = pos->next; pos != (head); \
+ pos = n, n = pos->next)
+
+static inline void INIT_LIST_HEAD(struct list_head *list) {
+ list->prev = list;
+ list->next = list;
+}
+
+/* Note: list_empty() on entry does not return true after this, the entry is
+ * in an undefined state.
+ */
+static inline void list_del(struct list_head *entry) {
+ entry->prev->next = entry->next;
+ entry->next->prev = entry->prev;
+ entry->next = NULL;
+ entry->prev = NULL;
+}
+
+static inline void list_add(struct list_head *entry, struct list_head *head) {
+ head->next->prev = entry;
+ entry->next = head->next;
+ entry->prev = head;
+ head->next = entry;
+}
+
+static inline void list_add_tail(struct list_head *entry, struct list_head *head) {
+ head->prev->next = entry;
+ entry->next = head;
+ entry->prev = head->prev;
+ head->prev = entry;
+}
+
+static inline int list_empty(struct list_head *head) {
+ return head->next == head;
+}
+
+
+#endif /* __LIST_H */
diff --git a/include/mmu.h b/include/mmu.h
@@ -6,10 +6,12 @@
#define PAGE_MASK (~(PAGE_SIZE - 1))
#define PAGE_ALIGN(x) (((x) + PAGE_SIZE - 1) & PAGE_MASK)
+#define L1_TYPE_MASK 3
#define L1_FAULT 0
#define L1_PAGE_TABLE 1
#define L1_SECTION 2
+#define L2_TYPE_MASK 3
#define L2_PAGE_FAULT 0
#define L2_LARGE_PAGE 1
#define L2_SMALL_PAGE 2
@@ -38,5 +40,6 @@ void mmu_init();
void mmu_enable();
void mmu_disable();
int mmu_map_page(void *phys, void *virt, uint_t npages, mmu_ap_t perms);
+int kmmap(void *virt, uint_t npages, mmu_ap_t perms);
#endif /* __MMU_H */
diff --git a/include/spinlock.h b/include/spinlock.h
@@ -0,0 +1,54 @@
+#ifndef __SPINLOCK_H
+#define __SPINLOCK_H
+
+#define SPINLOCK_INIT ((spinlock_t)0)
+
+typedef unsigned int spinlock_t;
+
+static inline void spinlock_lock(spinlock_t *sl) {
+ asm volatile (
+ "1: \n\t"
+ "ldrex v1, [%0] \n\t"
+ "teq v1, #0 \n\t"
+ "strexeq v1, %1, [%0] \n\t"
+ "teq v1, #0 \n\t"
+ "bne 1b \n\t"
+ :
+ : "r" (sl), "r" (0x80000000)
+ : "v1", "memory"
+ );
+}
+
+static inline void spinlock_unlock(spinlock_t *sl) {
+ asm volatile (
+ "str %1, [%0]"
+ :
+ : "r" (sl), "r" (0)
+ : "memory"
+ );
+}
+
+/* returns 1 if locked and 0 if not */
+static inline int spinlock_trylock(spinlock_t *sl) {
+ unsigned int tmp;
+
+ asm volatile (
+ "ldrex %0, [%1] \n\t"
+ "teq %0, #0 \n\t"
+ "strexeq %0, %2, [%1] \n\t"
+ : "=r" (tmp)
+ : "r" (sl), "r" (0x80000000)
+ : "memory"
+ );
+
+ if (tmp == 0)
+ return 1;
+ else
+ return 0;
+}
+
+static inline void INIT_SPINLOCK(spinlock_t *sl) {
+ *sl = 0;
+}
+
+#endif /* __SPINLOCK_H */
diff --git a/include/stddef.h b/include/stddef.h
@@ -1,6 +1,16 @@
#ifndef __STDDEF_H
#define __STDDEF_H
+#include <inttypes.h>
+
#define NULL ((void*)0)
+enum {
+ false = 0,
+ true = 1
+};
+
+
+#define offsetof(type, member) ((uintptr_t)&((type*)0)->member)
+
#endif /* __STDDEF_H */
diff --git a/include/string.h b/include/string.h
@@ -0,0 +1,47 @@
+#ifndef __STRING_H
+#define __STRING_H
+
+static inline void *memset(void *s, int c, size_t n) {
+ unsigned char *us = s;
+
+ while (n) {
+ *us = c;
+ us++;
+ n--;
+ }
+
+ return s;
+}
+
+static inline void *memcpy(void *s1, const void *s2, size_t n) {
+ unsigned char *us1 = s1;
+ const unsigned char *us2 = s2;
+
+ while (n) {
+ *us1 = *us2;
+ us1++;
+ us2++;
+ n--;
+ }
+
+ return s1;
+}
+
+static inline int memcmp(const void *s1, const void *s2, size_t n) {
+ const unsigned char *us1, *us2;
+
+ us1 = s1;
+ us2 = s2;
+
+ while (n) {
+ if (*us1 != *us2)
+ return (*us1 - *us2 < 0) ? -1 : 1;
+ us1++;
+ us2++;
+ n--;
+ }
+
+ return 0;
+}
+
+#endif /* __STRING_H */
diff --git a/kernel/alloc.c b/kernel/alloc.c
@@ -0,0 +1,146 @@
+#include <kernel.h>
+#include <list.h>
+#include <spinlock.h>
+#include <mmu.h>
+#include <alloc.h>
+
+struct mem_chunk {
+ union {
+ void *start;
+ uintptr_t start_a;
+ };
+ size_t size;
+ struct list_head list;
+};
+
+#define get_mem_chunk(addr) (((struct mem_chunk*)(addr)) - 1)
+
+static struct list_head freelist;
+static struct list_head alloclist;
+static spinlock_t freelist_lock = SPINLOCK_INIT;
+static spinlock_t alloclist_lock = SPINLOCK_INIT;
+static void *heap_last;
+
+extern void *_kernel_heap_start;
+extern void *_kernel_heap_end;
+
+static size_t roundup(size_t size) {
+ size_t ret;
+
+ if (size <= 16)
+ return 16;
+
+ /* get the number of leading zeros */
+ asm volatile("clz %0, %1" : "=r" (ret) : "r" (size));
+
+ /* round up to the next 'power of 2' number */
+ ret = 1 << (32 - ret);
+
+ if (size != (ret >> 1))
+ return ret;
+ else
+ return ret >> 1;
+}
+
+void *kmalloc(size_t size) {
+ int ret;
+ uint_t npages;
+ uintptr_t heap_last_a, tmp_addr;
+ struct mem_chunk *memc, *tmp_mc;
+ struct list_head *pos;
+
+ size = roundup(size);
+ heap_last_a = (uintptr_t)heap_last;
+
+ spinlock_lock(&freelist_lock);
+ list_for_each(pos, &freelist) {
+ memc = list_entry(pos, struct mem_chunk, list);
+ if (memc->size == size) {
+ list_del(&memc->list);
+ spinlock_unlock(&freelist_lock);
+ spinlock_lock(&alloclist_lock);
+ list_add(&memc->list, &alloclist);
+ spinlock_unlock(&alloclist_lock);
+ return memc->start;
+ }
+ }
+ spinlock_unlock(&freelist_lock);
+
+ npages = PAGE_ALIGN(sizeof(struct mem_chunk) + size) >> PAGE_SHIFT;
+
+ if (heap_last_a + npages * PAGE_SIZE > (uintptr_t)&_kernel_heap_end)
+ return NULL;
+
+ ret = kmmap(heap_last, npages, MMU_AP_RW_NONE);
+ if (ret < 0)
+ return NULL;
+
+ memc = heap_last;
+ memc->start_a = sizeof(struct mem_chunk) + heap_last_a;
+ memc->size = size;
+
+ spinlock_lock(&alloclist_lock);
+ list_add(&memc->list, &alloclist);
+ spinlock_unlock(&alloclist_lock);
+
+ heap_last_a += npages * PAGE_SIZE;
+ heap_last = (void*)heap_last_a;
+
+ tmp_addr = memc->start_a + memc->size;
+ while (tmp_addr + sizeof(struct mem_chunk) + memc->size < heap_last_a) {
+ tmp_mc = (void*)tmp_addr;
+ tmp_mc->start_a = sizeof(struct mem_chunk) + tmp_addr;
+ tmp_mc->size = memc->size;
+ tmp_addr += sizeof(struct mem_chunk) + tmp_mc->size;
+ spinlock_lock(&freelist_lock);
+ list_add(&tmp_mc->list, &freelist);
+ spinlock_unlock(&freelist_lock);
+ }
+
+ return memc->start;
+}
+
+void kfree(void *addr) {
+ struct mem_chunk *memc, *tmp;
+ struct list_head *pos;
+
+ memc = get_mem_chunk(addr);
+
+ spinlock_lock(&alloclist_lock);
+ list_for_each(pos, &alloclist) {
+ tmp = list_entry(pos, struct mem_chunk, list);
+ if (tmp == memc) {
+ list_del(&memc->list);
+ spinlock_lock(&freelist_lock);
+ list_add(&memc->list, &freelist);
+ spinlock_unlock(&freelist_lock);
+ break;
+ }
+ }
+ spinlock_unlock(&alloclist_lock);
+}
+
+
+void kdump() {
+ struct list_head *pos, *tmp;
+ struct mem_chunk *memc;
+
+ kprintf("alloc list\n");
+ list_for_each_safe(pos, tmp, &alloclist) {
+ memc = list_entry(pos, struct mem_chunk, list);
+ kprintf("%p %p %d\n", memc, memc->start, memc->size);
+ }
+
+ kprintf("\nfree list\n");
+ list_for_each_safe(pos, tmp, &freelist) {
+ memc = list_entry(pos, struct mem_chunk, list);
+ kprintf("%p %p %d\n", memc, memc->start, memc->size);
+ }
+}
+
+__attribute__ ((__constructor__))
+static void alloc_init() {
+ INIT_LIST_HEAD(&freelist);
+ INIT_LIST_HEAD(&alloclist);
+ heap_last = &_kernel_heap_start;
+}
diff --git a/kernel/debug.c b/kernel/debug.c
@@ -1,6 +1,5 @@
-#include <inttypes.h>
+#include <kernel.h>
#include <debug.h>
-#include <io.h>
static u32 *gpio_wk7 = (u32*)0x4A31E058;
static u32 *gpio_wk8 = (u32*)0x4A31E05C;
diff --git a/kernel/interrupts.S b/kernel/interrupts.S
@@ -1,6 +1,6 @@
.section .text
-.global init_vector_table
-init_vector_table:
+.global vector_table_init
+vector_table_init:
mrc p15, 0, r0, c1, c0, 0 @ read CP15 SCTRL register
bic r0, r0, #(1 << 13) @ set V flag to 0 (disable high vectors)
mcr p15, 0, r0, c1, c0, 0 @ write CP15 SCTRL register
diff --git a/kernel/kmain.c b/kernel/kmain.c
@@ -1,8 +1,9 @@
-#include <print.h>
-#include <debug.h>
+#include <kernel.h>
+#include <alloc.h>
+#include <string.h>
void kmain(void) {
- kprintf("voron initial stage\n");
+ kprintf("voron initial stage\n\n");
while (1)
asm volatile("wfi");
diff --git a/kernel/linker.ld b/kernel/linker.ld
@@ -18,6 +18,13 @@ SECTIONS
*(.data)
}
+ .init_array : ALIGN(4096)
+ {
+ _kernel_ctors_start = .;
+ *(.init_array)
+ _kernel_ctors_end = .;
+ }
+
.rodata : ALIGN(4096)
{
*(.rodata)
@@ -25,10 +32,16 @@ SECTIONS
.bss : ALIGN(4096)
{
+ _kernel_bss_start = .;
*(.bss)
}
. = ALIGN(4096);
+ _kernel_bss_end = .;
+
+ _kernel_heap_start = .;
+ . = . + 0x10000000;
+ _kernel_heap_end = .;
. = . + 0x2000;
_svc_stack_top = .;
diff --git a/kernel/mm.c b/kernel/mm.c
@@ -1,6 +1,5 @@
-#include <inttypes.h>
+#include <kernel.h>
#include <mmu.h>
-#include <errno.h>
#define ALIGN32(x) (((x) + 31) & ~31)
@@ -8,11 +7,15 @@ extern void *_ram_start;
extern void *_ram_end;
extern void *_kernel_bin_start;
extern void *_kernel_bin_end;
+extern void *_kernel_heap_start;
+extern void *_kernel_heap_end;
static u32 *bitmap;
static uint_t bitmapsz;
static uint_t kbound_s;
static uint_t kbound_e;
+static uint_t kheapbound_s;
+static uint_t kheapbound_e;
/* set range of bits */
static int set_bitmap_bits(uint_t start_bit, uint_t n, int flag) {
@@ -65,6 +68,8 @@ void mm_init() {
kbound_s = PAGE_ALIGN(PTR_DIFF(&_kernel_bin_start, &_ram_start)) >> PAGE_SHIFT;
kbound_e = PAGE_ALIGN(PTR_DIFF(&_kernel_bin_end, &_ram_start)) >> PAGE_SHIFT;
+ kheapbound_s = PAGE_ALIGN(PTR_DIFF(&_kernel_heap_start, &_ram_start)) >> PAGE_SHIFT;
+ kheapbound_e = PAGE_ALIGN(PTR_DIFF(&_kernel_heap_end, &_ram_start)) >> PAGE_SHIFT;
ramsz = PTR_DIFF(&_ram_end, &_ram_start) + 1;
bitmapsz = ALIGN32(ramsz >> PAGE_SHIFT) / 32;
@@ -74,7 +79,8 @@ void mm_init() {
for (i = 0; i < bitmapsz; i++)
bitmap[i] = 0;
- set_bitmap_bits(kbound_s, kbound_e - kbound_s, 1);
+ set_bitmap_bits(kbound_s, kheapbound_s - kbound_s, 1);
+ set_bitmap_bits(kheapbound_e, kbound_e - kheapbound_e, 1);
mmu_init();
@@ -83,7 +89,9 @@ void mm_init() {
0x40000, MMU_AP_RW_NONE);
/* map kernel memory */
mmu_map_page(&_kernel_bin_start, &_kernel_bin_start,
- kbound_e - kbound_s, MMU_AP_RW_NONE);
+ kheapbound_s - kbound_s, MMU_AP_RW_NONE);
+ mmu_map_page(&_kernel_heap_end, &_kernel_heap_end,
+ kbound_e - kheapbound_e, MMU_AP_RW_NONE);
mmu_enable();
}
@@ -94,7 +102,7 @@ void *palloc(uint_t npages) {
int ret;
if (npages == 0)
- return (void*)-EINVAL;
+ return ERR_PTR(-EINVAL);
n = 0;
for (i = 0; i < bitmapsz; i++) {
@@ -114,12 +122,12 @@ void *palloc(uint_t npages) {
n = 0;
}
- return (void*)-EINVAL;
+ return ERR_PTR(-EINVAL);
out:
ret = set_bitmap_bits(sbit, npages, 1);
if (ret < 0)
- return (void*)ret;
+ return ERR_PTR(ret);
return (void*)((uintptr_t)sbit * PAGE_SIZE + (uintptr_t)&_ram_start);
}
@@ -135,7 +143,8 @@ int pfree(void *paddr, uint_t npages) {
sbit = (paddr_a - (uintptr_t)&_ram_start) >> PAGE_SHIFT;
/* we cannot free the memory of ourself */
- if (sbit >= kbound_s && sbit < kbound_e)
+ if ((sbit >= kbound_s && sbit < kheapbound_s) ||
+ (sbit >= kheapbound_e && sbit < kbound_e))
return -EINVAL;
return set_bitmap_bits(sbit, npages, 0);
diff --git a/kernel/mmu.c b/kernel/mmu.c
@@ -1,8 +1,6 @@
-#include <inttypes.h>
+#include <kernel.h>
#include <mmu.h>
-#include <errno.h>
-#include <debug.h>
-#include <print.h>
+#include <mm.h>
static u32 mmu_ttb[4096] __attribute__((__aligned__ (16 * 1024)));
static u32 l2[4096][256] __attribute__((__aligned__ (1024)));
@@ -59,6 +57,32 @@ void mmu_disable() {
);
}
+static int is_mapped_virt(void *virt) {
+ uint_t pte_idx, pde_idx;
+ u32 *pde;
+ uintptr_t virt_a;
+
+ virt_a = (uintptr_t)virt;
+ pde_idx = virt_a >> 20;
+
+ switch (mmu_ttb[pde_idx] & L1_TYPE_MASK) {
+ case 1: /* page table */
+ pde = (u32*)(mmu_ttb[pde_idx] & ~0x3ff);
+ pte_idx = (virt_a & 0xff000) >> 12;
+ if (pde[pte_idx] & L2_TYPE_MASK)
+ return 1;
+ else
+ return 0; /* fault */
+ case 2: /* section */
+ return 1;
+ case 0: /* fault */
+ default:
+ return 0;
+ }
+
+ return 0;
+}
+
/* map physical memory to virtual memory */
int mmu_map_page(void *phys, void *virt, uint_t npages, mmu_ap_t perms) {
u32 pte, pte_perms;
@@ -126,3 +150,31 @@ int mmu_map_page(void *phys, void *virt, uint_t npages, mmu_ap_t perms) {
return 0;
}
+
+int kmmap(void *virt, uint_t npages, mmu_ap_t perms) {
+ uint_t i;
+ uintptr_t virt_a;
+ void *pa;
+
+ if (npages == 0)
+ return -EINVAL;
+
+ virt_a = (uintptr_t)virt;
+
+ /* overflow */
+ if (virt_a + npages * PAGE_SIZE < virt_a)
+ return -EFAULT;
+
+ for (i = 0; i < npages; i++) {
+ if (is_mapped_virt((void*)virt_a)) {
+ kprintf("WARNING: %p virtual address is already maped\n", virt);
+ virt_a += PAGE_SIZE;
+ continue;
+ }
+ pa = palloc(1);
+ mmu_map_page(pa, virt, 1, perms);
+ virt_a += PAGE_SIZE;
+ }
+
+ return 0;
+}
diff --git a/kernel/print.c b/kernel/print.c
@@ -1,7 +1,5 @@
-#include <inttypes.h>
+#include <kernel.h>
#include <rs232.h>
-#include <print.h>
-#include <varg.h>
int kputs(const char *s) {
return rs232_puts(s);
diff --git a/kernel/rs232.c b/kernel/rs232.c
@@ -1,7 +1,6 @@
-#include <inttypes.h>
+#include <kernel.h>
#include <rs232.h>
#include <uart.h>
-#include <io.h>
static struct uart *uart = (struct uart*)0x48020000;
diff --git a/kernel/start.S b/kernel/start.S
@@ -14,8 +14,18 @@ _start:
ldr r0, =boot_msg
bl kputs
+ /* init .bss section */
+ ldr r0, =_kernel_bss_start
+ ldr r1, =_kernel_bss_end
+ mov r2, #0
+ mov r3, #0
+1:
+ stmia r0!, { r2, r3 }
+ cmp r0, r1
+ blo 1b
+
/* initialize vector table */
- bl init_vector_table
+ bl vector_table_init
/* disable caches for now */
mrc p15, 0, r0, c1, c0, 0
@@ -34,6 +44,21 @@ _start:
bl mm_init
+ /* run constructors */
+ ldr r0, =_kernel_ctors_start
+ ldr r1, =_kernel_ctors_end
+1:
+ teq r0, r1
+ beq 2f
+ ldr r2, [r0], #4
+ stmfd sp!, { r0, r1 }
+ ldr lr, =.Lctor_ret
+ mov pc, r2
+.Lctor_ret:
+ ldmfd sp!, { r0, r1 }
+ b 1b
+2:
+
/* example of calling a system call with at least 6 arguments */
mov r0, #1
mov r1, #2
diff --git a/kernel/syscalls.c b/kernel/syscalls.c
@@ -1,5 +1,4 @@
-#include <print.h>
-#include <inttypes.h>
+#include <kernel.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);
diff --git a/usbboot/usbboot.S b/usbboot/usbboot.S
@@ -9,11 +9,11 @@ _start:
ldr r1, =_image_end
ldr r2, =_image_load_addr
-.L1:
+1:
ldmia r0!, { r3 - r12 }
stmia r2!, { r3 - r12 }
cmp r0, r1
- blo .L1
+ blo 1b
ldmfd sp!, { r0 - r12 }
ldr pc, =_image_load_addr @ jump to _image_load_addr