summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile5
-rw-r--r--include/asm/io.h4
-rw-r--r--include/asm/system.h3
-rw-r--r--include/kernel/memory.h18
-rw-r--r--include/kernel/sched.h26
-rw-r--r--include/string.h37
-rw-r--r--kernel/Makefile2
-rw-r--r--kernel/asm.s60
-rw-r--r--kernel/boot.s4
-rw-r--r--kernel/kmain.c5
-rw-r--r--kernel/memory.c129
-rw-r--r--kernel/page.s55
-rw-r--r--kernel/sched.c131
-rw-r--r--kernel/usrspace.s45
-rw-r--r--lib/Makefile29
-rw-r--r--lib/string.c173
-rw-r--r--usrbin/Makefile7
-rw-r--r--usrbin/link.ld2
18 files changed, 625 insertions, 110 deletions
diff --git a/Makefile b/Makefile
index c45c277..c29b673 100644
--- a/Makefile
+++ b/Makefile
@@ -10,15 +10,18 @@ build: $(TARGET)
$(TARGET): .FORCE
$(MAKE) -C kernel
+ $(MAKE) -C lib
$(MAKE) -C usrbin
- $(LD) -o $(TARGET) kernel/kernel.o usrbin/usrbin_blob.o
+ $(LD) -o $(TARGET) kernel/kernel.o usrbin/usrbin_blob.o lib/lib.a
clean:
$(MAKE) -C kernel clean
+ $(MAKE) -C lib clean
$(MAKE) -C usrbin clean
rm -f $(TARGET)
run: $(TARGET)
qemu-system-x86_64 -s -kernel $(TARGET)
+ # qemu-system-x86_64 -s -S -kernel $(TARGET)
.FORCE:
diff --git a/include/asm/io.h b/include/asm/io.h
index 6ca5bbc..1c2e5bc 100644
--- a/include/asm/io.h
+++ b/include/asm/io.h
@@ -6,9 +6,9 @@
#define inb(port) ({ \
unsigned char _val; \
- asm volatile ("inb %%dx, %%al" : "=a" (_val) : "d" (port)); \
+ __asm__ volatile ("inb %%dx, %%al" : "=a" (_val) : "d" (port)); \
_val; \
})
#define outb(port, val) \
- asm volatile ("outb %%al, %%dx" : : "d" (port), "a" (val));
+ __asm__ volatile ("outb %%al, %%dx" : : "d" (port), "a" (val));
diff --git a/include/asm/system.h b/include/asm/system.h
new file mode 100644
index 0000000..02c2f62
--- /dev/null
+++ b/include/asm/system.h
@@ -0,0 +1,3 @@
+#include <kernel/sched.h>
+
+volatile void switch_to(struct task_struct*, struct task_state*);
diff --git a/include/kernel/memory.h b/include/kernel/memory.h
new file mode 100644
index 0000000..7217427
--- /dev/null
+++ b/include/kernel/memory.h
@@ -0,0 +1,18 @@
+#include <stdint.h>
+
+#define PGENT 1024
+
+typedef uint32_t pte_t;
+typedef uint32_t __attribute__((aligned (4096))) ptab_t[PGENT];
+typedef uint32_t pde_t;
+typedef uint32_t __attribute__((aligned (4096))) pdir_t[PGENT];
+
+extern ptab_t ktab;
+
+void *alloc_physical_page(void);
+int free_physical_page(void*);
+void *alloc_physical_pages(unsigned int);
+
+void *map_page(void*);
+
+void paging_init(void);
diff --git a/include/kernel/sched.h b/include/kernel/sched.h
new file mode 100644
index 0000000..fa8e036
--- /dev/null
+++ b/include/kernel/sched.h
@@ -0,0 +1,26 @@
+#ifndef _SCHED_H
+#define _SCHED_H
+
+#include <stdint.h>
+
+struct task_state {
+ uint32_t ss;
+ uint32_t esp;
+ uint32_t eflags;
+ uint32_t cs;
+ uint32_t eip;
+ uint32_t eax;
+ uint32_t ecx;
+ uint32_t edx;
+ uint32_t ebx;
+ uint32_t esp_garbage;
+ uint32_t ebp;
+ uint32_t esi;
+ uint32_t edi;
+} __attribute__((packed));
+
+struct task_struct {
+ struct task_state state;
+} __attribute__((packed));
+
+#endif
diff --git a/include/string.h b/include/string.h
new file mode 100644
index 0000000..72c2b2e
--- /dev/null
+++ b/include/string.h
@@ -0,0 +1,37 @@
+#ifndef STRING_H
+#define STRING_H
+
+#include <stdint.h>
+
+#ifndef NULL
+#define NULL ((void*) 0)
+#endif
+
+#ifndef _SIZE_T
+#define _SIZE_T
+typedef uint32_t size_t;
+#endif
+
+void* memchr(const void*, int, size_t);
+int memcmp(const void*, const void*, size_t);
+void* memcpy(void*, const void*, size_t);
+void* memmove(void*, const void*, size_t);
+void* memset(void*, int, size_t);
+
+size_t strlen(const char*);
+char* strcat(char*, const char*);
+char* strncat(char*, const char*, size_t);
+char* strchr(const char*, int);
+char* strrchr(char*, int);
+int strcmp(const char*, const char*);
+int strncmp(const char*, const char*, size_t);
+char* strcpy(char*, const char*);
+char* strncpy(char*, const char*, size_t);
+size_t strcspn(const char*, const char*);
+size_t strspn(const char*, const char*);
+char* strpbrk(const char*, const char*);
+char* strstr(const char*, const char*);
+char* strtok(char*, const char*);
+size_t strxfrm(char*, const char*, size_t);
+
+#endif
diff --git a/kernel/Makefile b/kernel/Makefile
index c6cf24e..29b5566 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -4,7 +4,7 @@ SRCS = $(wildcard *.c)
ASMS = $(wildcard *.s)
OBJS = $(SRCS:.c=.o) $(ASMS:.s=.o)
-CFLAGS = -m32 -I../include -ffreestanding -nostdinc -nostdlib -fno-stack-protector -fno-pie -gstabs+
+CFLAGS = -m32 -I../include -ffreestanding -nostdinc -nostdlib -fno-stack-protector -fno-pie -gstabs+ -g
LDFLAGS = -m elf_i386 -r
ASMFLAGS = -f elf32
diff --git a/kernel/asm.s b/kernel/asm.s
new file mode 100644
index 0000000..4abe607
--- /dev/null
+++ b/kernel/asm.s
@@ -0,0 +1,60 @@
+global switch_to
+extern ctask
+extern tss
+
+switch_to:
+ push ebp
+ mov ebp, esp
+ mov eax, [ebp+8]
+ mov [ctask], eax
+ mov esi, [ebp+12]
+ mov ecx, 13
+.loop:
+ lodsd
+ push eax
+ dec ecx
+ jz .end
+ jmp .loop
+.end:
+ mov ax, 0x23
+ mov ds, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
+ popa
+ iret
+
+; uint32_t ss;
+; uint32_t esp;
+; uint32_t eflags;
+; uint32_t cs;
+; uint32_t eip;
+; uint32_t eax;
+; uint32_t ecx;
+; uint32_t edx;
+; uint32_t ebx;
+; uint32_t esp_garbage;
+; uint32_t ebp;
+; uint32_t esi;
+; uint32_t edi;
+
+; switch_to:
+ ; push ebp
+ ; mov ebp, esp
+ ; cli
+ ; mov ax, 0x23
+ ; mov ds, ax
+ ; mov es, ax
+ ; mov fs, ax
+ ; mov gs, ax
+ ; mov eax, esp
+ ; ; save ESP in the TSS
+ ; mov [tss+4], eax
+ ; push dword 0x23
+ ; push dword 0x00180000
+ ; pushf
+ ; push dword 0x1B
+ ; push dword 0x00100000
+ ; iret
+ ; pop ebp
+ ; ret
diff --git a/kernel/boot.s b/kernel/boot.s
index 80f8be9..9d948cf 100644
--- a/kernel/boot.s
+++ b/kernel/boot.s
@@ -22,6 +22,8 @@ section .text
kboot:
cli
; put the stack pointer near the end of conventional memory
+ ; WARNING: don't change this without changing the corresponding
+ ; entry in the TSS
mov esp, 0x80000
; setup descriptor tables
call flush_gdt
@@ -37,7 +39,7 @@ kboot:
tss:
dd 0
- dd 0 ; kernel stack pointer
+ dd 0x80000 ; kernel stack pointer
dd 0x10 ; kernel stack segment
times 60 db 0
dd 0x13 ; ES segment
diff --git a/kernel/kmain.c b/kernel/kmain.c
index ece7012..558df42 100644
--- a/kernel/kmain.c
+++ b/kernel/kmain.c
@@ -1,12 +1,13 @@
#include <kernel/con.h>
+#include <kernel/memory.h>
#include <kernel/sys.h>
#include <stdint.h>
#include <sys/types.h>
-uint32_t ticks = 0;
-
extern void userspace_init(void);
+uint32_t ticks = 0;
+
void kmain(void) {
con_init();
diff --git a/kernel/memory.c b/kernel/memory.c
new file mode 100644
index 0000000..465b44f
--- /dev/null
+++ b/kernel/memory.c
@@ -0,0 +1,129 @@
+#include <kernel/memory.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+static char __attribute__((aligned (4096))) mapped_page[4096];
+
+static pdir_t kpdir;
+
+ptab_t ktab;
+
+static ptab_t flow;
+static ptab_t fupp;
+
+void *alloc_physical_page(void) {
+ int i;
+ void *ret;
+
+ for(i = 0; i < PGENT; i++) {
+ if(flow[i] & 1) {
+ ret = (void*) (flow[i] & ~1);
+ flow[i] = 0;
+ return ret;
+ }
+
+ if(fupp[i] & 1) {
+ ret = (void*) (fupp[i] & ~1);
+ fupp[i] = 0;
+ return ret;
+ }
+ }
+
+ return NULL;
+}
+
+int free_physical_page(void *page) {
+ int i;
+ page = (void*) ((uint32_t) page & ~0xFFF);
+
+ for(int i = 0; i < PGENT; i++) {
+ if(!(flow[i] & 1)) {
+ flow[i] = (uint32_t) page | 1;
+ return 0;
+ }
+
+ if(!(fupp[i] & 1)) {
+ fupp[i] = (uint32_t) page | 1;
+ return 0;
+ }
+ }
+
+ return -1;
+}
+
+void *alloc_physical_pages(unsigned int n) {
+ void *p = NULL;
+ void *last = NULL;
+ void **page;
+
+ while(n--) {
+ p = alloc_physical_page();
+ if(p == NULL) {
+ page = &last;
+ while(*page) {
+ free_physical_page(*page);
+ page = *page;
+ }
+ return NULL;
+ }
+
+ map_page(p);
+ *((void**) mapped_page) = last;
+ last = p;
+ }
+
+ return p;
+}
+
+void *map_page(void *page) {
+ uint32_t p = (uint32_t) mapped_page;
+
+ /* enforce 4KB page alignment */
+ page = (void*) ((uint32_t) page & ~0xFFF);
+
+ ktab[(p >> 12) & 0x3FF] = (uint32_t) page | 0x003;
+ /*
+ * invalidate any cached entries for
+ * the mapped page window.
+ */
+ __asm__ ("invlpg %0" :: "m" (mapped_page));
+
+ return mapped_page;
+}
+
+void paging_init(void) {
+ int i;
+
+ /* empty the page directory */
+ for(i = 0; i < PGENT; i++)
+ kpdir[i] = 0;
+
+ /* populate the free page tables */
+ for(i = 0; i < PGENT; i++) {
+ /* populate the lower table */
+ flow[i] = (i << 12);
+ /* only pages >1MB can be allocated */
+ if(i >= 0x100)
+ flow[i] |= 0x001;
+ /* populate the upper table */
+ fupp[i] = ((i << 12) + 0x400000) | 0x001;
+ }
+
+ /* populate the kernel's page table */
+ for(i = 0; i < PGENT; i++) {
+ ktab[i] = 0;
+ if(i < 256)
+ ktab[i] = (i << 12) | 0x003;
+ }
+
+ /* populate the kernel's page directory */
+ kpdir[0] = ((pde_t) ktab) | 0x007;
+
+ __asm__ (
+ "mov %%eax, %%cr3\n"
+ "mov %%cr0, %%eax\n"
+ "or $0x80000000, %%eax\n"
+ "mov %%eax, %%cr0\n"
+ :: "a" (&kpdir)
+ :);
+}
diff --git a/kernel/page.s b/kernel/page.s
deleted file mode 100644
index 4e40822..0000000
--- a/kernel/page.s
+++ /dev/null
@@ -1,55 +0,0 @@
-global paging_init
-
-align 4096
-page_dir:
- times 4096 db 0
-
-align 4096
-page_tables:
- ; two page tables
- times 4096 db 0
- times 4096 db 0
-.end:
-
-; here, we initialize paging. since the IDT
-; has yet to be populated, we must take extra
-; care as we can't afford to trigger a page
-; fault.
-paging_init:
- push ebp
- mov ebp, esp
- push ebx
- ; populate the page directory
- mov eax, page_tables
- or eax, 0x007
- mov [page_dir], eax
- mov eax, (page_tables+4096)
- or eax, 0x007
- mov [page_dir+4], eax
- ; populate the page tables
- mov ebx, page_tables
- mov ecx, ((page_tables.end-page_tables)/4)
- mov edx, 0
-.loop:
- mov eax, edx
- or eax, 0x003
- cmp edx, 0x100000
- jb .skip
- or eax, 0x004
-.skip:
- mov [ebx], eax
- dec ecx
- jz .end
- add ebx, 4
- add edx, 4096
- jmp .loop
-.end:
- ; load the page directory and enable paging
- mov eax, page_dir
- mov cr3, eax
- mov eax, cr0
- or eax, 0x80000000
- mov cr0, eax
- pop ebx
- pop ebp
- ret
diff --git a/kernel/sched.c b/kernel/sched.c
new file mode 100644
index 0000000..f0b79fc
--- /dev/null
+++ b/kernel/sched.c
@@ -0,0 +1,131 @@
+#include <asm/system.h>
+#include <kernel/con.h>
+#include <kernel/memory.h>
+#include <kernel/sched.h>
+#include <string.h>
+#include <sys/types.h>
+
+#define USRSTART ((void*) 0x40000000)
+
+#define pages(n) \
+ ((n / 4096) + 1)
+
+#define tables(n) \
+ ((n / 1024) + 1)
+
+#define getpage(name, p) ({\
+ void **_next; \
+ _next = map_page(p); \
+ name = p; \
+ p = *_next; \
+ })
+
+extern char _usrbin_start;
+extern char _usrbin_size;
+
+struct task_struct *ctask;
+
+static struct task_struct task;
+
+static inline void empty_table(void *t) {
+ int i;
+
+ for(i = 0; i < PGENT; i++)
+ ((uint32_t*) t)[i] = 0;
+}
+
+void userspace_init(void) {
+ int i, j;
+ int c;
+ size_t totpages, npages, ntables;
+ void *p, *page, *tab, *map;
+ void *pdir, *stackt, *stackp;
+
+ size_t usrsize = (size_t) &_usrbin_size;
+
+ npages = pages(usrsize);
+ ntables = tables(pages(usrsize));
+ totpages = npages + ntables + 3;
+
+ /* here we allocate pages to setup the process'
+ * address space. in addition to the pages that
+ * will hold the binary image, the following
+ * pages are allocated:
+ * - page directory (1 page)
+ * - page tables
+ * - stack page (1 page)
+ * - stack table (1 page)
+ */
+ p = alloc_physical_pages(totpages);
+ printf("Allocating %x pages for userspace process\n", totpages);
+ if(p == NULL) {
+ printf("Failed to allocate memory for userspace!\n");
+ return;
+ }
+
+ getpage(pdir, p);
+ getpage(stackt, p);
+ getpage(stackp, p);
+ printf(" Page directory: 0x%08x\n", (uint32_t) pdir);
+ printf(" Stack table: 0x%08x\n", (uint32_t) stackt);
+ printf(" Stack page: 0x%08x\n", (uint32_t) stackp);
+ printf(" Page tables:\n");
+
+ /* populate the page directory */
+ c = npages;
+ map = map_page(pdir);
+ empty_table(map);
+ for(i = 0; i < ntables; i++) {
+ /* add the table entry to the directory */
+ getpage(tab, p);
+ printf(" 0x%08x\n", (uint32_t) tab);
+ map = map_page(pdir);
+ ((uint32_t*) map)[i + (PGENT / 4)] = (uint32_t) tab | 0x007;
+
+ /* populate the page table */
+ map = map_page(tab);
+ for(j = 0; j < PGENT; j++) {
+ ((uint32_t*) map)[j] = 0;
+ if(c <= 0)
+ continue;
+
+ getpage(page, p);
+ map = map_page(tab);
+ ((uint32_t*) map)[j] = (uint32_t) page | 0x007;
+ c--;
+ }
+ }
+
+ /* populate the stack table */
+ map = map_page(stackt);
+ empty_table(map);
+ ((uint32_t*) map)[PGENT - 1] = (uint32_t) stackp | 0x007;
+
+ /* add the stack page table to the directory */
+ map = map_page(pdir);
+ ((uint32_t*) map)[PGENT - 1] = (uint32_t) stackt | 0x007;
+ /* add the kernel's page table to the directory */
+ ((uint32_t*) map)[0] = (uint32_t) ktab | 0x003;
+
+ __asm__ volatile ("mov %%eax, %%cr3" :: "a" (pdir));
+
+ memcpy(USRSTART, &_usrbin_start, usrsize);
+
+ /*
+ * here we initialize the task struct.
+ * currently, we only setup state information
+ * necessary to begin execution.
+ */
+ memset(&task, 0, sizeof(task));
+ task.state.cs = 0x1B;
+ task.state.ss = 0x23;
+ task.state.eip = (uint32_t) USRSTART;
+ task.state.esp = 0xFFFFFFFF;
+ __asm__ (
+ "pushf\n" \
+ "pop %%eax" \
+ : "=a" (task.state.eflags) \
+ ::);
+
+ switch_to(&task, &task.state);
+}
diff --git a/kernel/usrspace.s b/kernel/usrspace.s
deleted file mode 100644
index 1d20f71..0000000
--- a/kernel/usrspace.s
+++ /dev/null
@@ -1,45 +0,0 @@
-global userspace_init
-extern _binary_usrbin_bin_size
-extern _binary_usrbin_bin_start
-extern tss
-
-userspace_init:
- push ebp
- mov ebp, esp
- push esi
- push edi
- mov ecx, _binary_usrbin_bin_size
- mov esi, _binary_usrbin_bin_start
- mov edi, 0x100000
-.loop:
- movsb
- dec ecx
- jz .end
- jmp .loop
-.end:
- pop edi
- pop esi
- call usrcall
- pop ebp
- ret
-
-usrcall:
- push ebp
- mov ebp, esp
- cli
- mov ax, 0x23
- mov ds, ax
- mov es, ax
- mov fs, ax
- mov gs, ax
- mov eax, esp
- ; save ESP in the TSS
- mov [tss+4], eax
- push dword 0x23
- push dword 0x00180000
- pushf
- push dword 0x1B
- push dword 0x00100000
- iret
- pop ebp
- ret
diff --git a/lib/Makefile b/lib/Makefile
new file mode 100644
index 0000000..13c92f2
--- /dev/null
+++ b/lib/Makefile
@@ -0,0 +1,29 @@
+TARGET = lib.a
+
+SRCS = $(wildcard *.c)
+ASMS = $(wildcard *.s)
+OBJS = $(SRCS:.c=.o) $(ASMS:.s=.o)
+
+CFLAGS = -m32 -I../include -ffreestanding -nostdinc -nostdlib -fno-stack-protector -fno-pie -gstabs+ -g
+ASMFLAGS = -f elf32
+
+AR = ar
+CC = gcc $(CFLAGS)
+ASM = nasm $(ASMFLAGS)
+
+all: build
+
+build: $(TARGET)
+
+.s.o:
+ $(ASM) -o $*.o $^
+
+.c.o:
+ $(CC) -c -o $*.o $^
+
+$(TARGET): $(OBJS)
+ $(AR) rc $(TARGET) $(OBJS)
+
+clean:
+ rm -f $(OBJS)
+ rm -f $(TARGET)
diff --git a/lib/string.c b/lib/string.c
new file mode 100644
index 0000000..0e8fbeb
--- /dev/null
+++ b/lib/string.c
@@ -0,0 +1,173 @@
+#include <string.h>
+
+void* memchr(const void* s, int c, size_t n) {
+ unsigned char *p = (unsigned char*) s;
+ while(n--) {
+ if(*p != (unsigned char) c) {
+ p++;
+ } else {
+ return p;
+ }
+ }
+ return 0;
+}
+
+int memcmp(const void* s1, const void* s2, size_t n) {
+ const unsigned char* p1 = (const unsigned char*) s1;
+ const unsigned char* p2 = (const unsigned char*) s2;
+ while(n--) {
+ if(*p1 != *p2) {
+ return *p1 - *p2;
+ } else {
+ p1++, p2++;
+ }
+ }
+ return 0;
+}
+
+void* memcpy(void* dest, const void* src, size_t n) {
+ char *dp = (char*) dest;
+ const char *sp = (const char*) src;
+ while(n--) *dp++ = *sp++;
+ return dest;
+}
+
+void* memmove(void* dest, const void* src, size_t n) {
+ unsigned char tmp[n];
+ memcpy(tmp, src, n);
+ memcpy(dest, tmp, n);
+ return dest;
+}
+
+void* memset(void* s, int c, size_t n) {
+ unsigned char* p = (unsigned char*) s;
+ while(n--) *p++ = (unsigned char) c;
+ return s;
+}
+
+size_t strlen(const char* str) {
+ const char* s;
+ for(s = str; *s; ++s) {}
+ return (s - str);
+}
+
+char* strcat(char* dest, const char* src) {
+ size_t dest_len = strlen(dest);
+ size_t i;
+
+ for(i = 0; src[i] != '\0'; i++) {
+ dest[dest_len + i] = src[i];
+ }
+ dest[dest_len + i] = '\0';
+ return dest;
+}
+
+char* strncat(char* dest, const char* src, size_t n) {
+ size_t dest_len = strlen(dest);
+ size_t i;
+
+ for(i = 0; i < n && src[i] != '\0'; i++) {
+ dest[dest_len + i] = src[i];
+ }
+ dest[dest_len + i] = '\0';
+ return dest;
+}
+
+char* strchr(const char* s, int c) {
+ while(*s != (char) c) {
+ if(!*s++) return 0;
+ }
+ return (char*) s;
+}
+
+char* strrchr(char* s, int c) {
+ char* ret = 0;
+ do {
+ if(*s == (char) c) ret = s;
+ } while(*s++);
+ return ret;
+}
+
+int strcmp(const char* s1, const char* s2) {
+ while(*s1 && (*s1 == *s2)) s1++, s2++;
+ return *(const unsigned char*) s1 - *(const unsigned char*) s2;
+}
+
+int strncmp(const char* s1, const char* s2, size_t n) {
+ while(n--) {
+ if(*s1++ != *s2++) {
+ return *(unsigned char*) (s1 - 1) - *(unsigned char*) (s2 - 1);
+ }
+ }
+ return 0;
+}
+
+char* strcpy(char* dest, const char* src) {
+ char* ret = dest;
+ while(*dest++ = *src++);
+ return ret;
+}
+
+char* strncpy(char* dest, const char* src, size_t n) {
+ char* ret = dest;
+ do {
+ if(!n--) return ret;
+ } while (*dest++ = *src++);
+ while(n--) *dest++ = 0;
+ return ret;
+}
+
+size_t strcspn(const char* s1, const char* s2) {
+ size_t ret = 0;
+ while(*s1) {
+ if(strchr(s2, *s1)) {
+ return ret;
+ } else {
+ s1++, ret++;
+ }
+ }
+ return ret;
+}
+
+size_t strspn(const char* s1, const char* s2) {
+ size_t ret = 0;
+ while(*s1 && strchr(s2, *s1++)) ret++;
+ return ret;
+}
+
+char* strpbrk(const char* s1, const char* s2) {
+ while(*s1) {
+ if(strchr(s2, *s1++)) return (char*) --s1;
+ }
+ return 0;
+}
+
+char* strstr(const char* s1, const char* s2) {
+ size_t n = strlen(s2);
+ while(*s1) {
+ if(!memcmp(s1++, s2, n)) {
+ return (char*) (s1 - 1);
+ }
+ }
+ return 0;
+}
+
+char* strtok(char* str, const char* delim) {
+ static char* p = 0;
+ if(str) {
+ p = str;
+ } else if(!p) {
+ return 0;
+ }
+ str = p + strspn(p, delim);
+ p = str + strcspn(str, delim);
+ if(p == str) return p = 0;
+ p = *p ? *p = 0, p + 1 : 0;
+ return str;
+}
+
+size_t strxfrm(char* dest, const char* src, size_t n) {
+ size_t n2 = strlen(src);
+ if(n > n2) strcpy(dest, src);
+ return n2;
+}
diff --git a/usrbin/Makefile b/usrbin/Makefile
index 16a607f..9a40cbc 100644
--- a/usrbin/Makefile
+++ b/usrbin/Makefile
@@ -4,7 +4,7 @@ SRCS = $(wildcard *.c)
ASMS = $(wildcard *.s)
OBJS = $(SRCS:.c=.o) $(ASMS:.s=.o)
-CFLAGS = -m32 -I../include -ffreestanding -nostdinc -nostdlib -fno-stack-protector -fno-pie
+CFLAGS = -m32 -I../include -ffreestanding -nostdinc -nostdlib -fno-stack-protector -fno-pie -g
LDFLAGS = -m elf_i386 -T link.ld
ASMFLAGS = -f elf32
@@ -24,7 +24,10 @@ build: $(TARGET)
$(TARGET): $(OBJS)
$(LD) -o usrbin.bin $(OBJS)
- objcopy -I binary -O elf32-i386 -B i386 usrbin.bin $(TARGET)
+ objcopy -I binary -O elf32-i386 -B i386 usrbin.bin $(TARGET) \
+ --redefine-sym _binary_usrbin_bin_start=_usrbin_start \
+ --redefine-sym _binary_usrbin_bin_end=_usrbin_end \
+ --redefine-sym _binary_usrbin_bin_size=_usrbin_size
clean:
rm -f usrbin.bin
diff --git a/usrbin/link.ld b/usrbin/link.ld
index c1a7a42..57edac9 100644
--- a/usrbin/link.ld
+++ b/usrbin/link.ld
@@ -1,7 +1,7 @@
OUTPUT_FORMAT(binary)
SECTIONS
{
- . = 0x100000;
+ . = 0x40000000;
.text : { *(.entry); .*(.text) }
.data : { *(.data) }
.bss : { *(.bss) }