aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/fbos/compiler.h6
-rw-r--r--include/fbos/init.h4
-rw-r--r--include/fbos/sched.h6
-rw-r--r--kernel/head.S4
-rw-r--r--kernel/initrd.c40
-rw-r--r--kernel/main.c15
-rw-r--r--test/test_initrd.c13
-rw-r--r--usr/src/bar.S4
-rw-r--r--usr/src/foo.S4
-rw-r--r--usr/src/foobar.S4
10 files changed, 79 insertions, 21 deletions
diff --git a/include/fbos/compiler.h b/include/fbos/compiler.h
index b88bb0b..c26c05c 100644
--- a/include/fbos/compiler.h
+++ b/include/fbos/compiler.h
@@ -19,16 +19,18 @@
#endif /* __KERNEL__ */
/*
- * Multiple aliases for 32/64-bit integers which have their definition on the
+ * Multiple aliases for integer types which have their definition on the
* standard library.
*/
+typedef short int16_t;
typedef int int32_t;
typedef long ssize_t;
typedef long int64_t;
-typedef unsigned long size_t;
+typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
+typedef unsigned long size_t;
typedef unsigned long uint64_t;
typedef unsigned long uintptr_t;
diff --git a/include/fbos/init.h b/include/fbos/init.h
index c4d0a85..978eebe 100644
--- a/include/fbos/init.h
+++ b/include/fbos/init.h
@@ -3,11 +3,9 @@
#include <fbos/compiler.h>
-extern struct task_struct init_task;
-
// Extract the executables from the initrd that is located at `base_addr` and
// has the given `size`.
-void extract_initrd(const char *const base_addr, uint64_t size);
+void extract_initrd(const unsigned char *const base_addr, uint64_t size);
// The entry point for the kernel.
void start_kernel(void *dtb);
diff --git a/include/fbos/sched.h b/include/fbos/sched.h
index 5cfc2ba..ff56f32 100644
--- a/include/fbos/sched.h
+++ b/include/fbos/sched.h
@@ -1,6 +1,8 @@
#ifndef __FBOS_SCHED_H_
#define __FBOS_SCHED_H_
+#include <fbos/compiler.h>
+
enum task_id {
TASK_UNKNOWN = -1,
TASK_INIT = 0,
@@ -11,6 +13,10 @@ enum task_id {
struct task_struct {
void *stack;
+ const void *addr;
+ uint64_t entry_offset;
};
+extern struct task_struct tasks[4];
+
#endif // __FBOS_SCHED_H_
diff --git a/kernel/head.S b/kernel/head.S
index de7852b..9018a8e 100644
--- a/kernel/head.S
+++ b/kernel/head.S
@@ -43,8 +43,8 @@ _start:
csrw sscratch, 0
// Point tp and sp to the init task.
- la tp, init_task
- la sp, init_task + THREAD_SIZE
+ la tp, tasks
+ la sp, tasks + THREAD_SIZE
// The `start_kernel` function requires an argument to be passed, which is
// the pointer to the `fdt` blob. The bootloader puts this on the `a1`
diff --git a/kernel/initrd.c b/kernel/initrd.c
index c05e77d..4706fe8 100644
--- a/kernel/initrd.c
+++ b/kernel/initrd.c
@@ -63,16 +63,48 @@ __kernel int get_task_id_from_name(const char *const name)
return TASK_UNKNOWN;
}
-__kernel void extract_elf(int task_id, const char *const addr, size_t size)
+__kernel void ensure_elf_format(const unsigned char *const addr)
+{
+ if (addr[0] != 0x7F || memcmp(&addr[1], "ELF", 3) != 0) {
+ die("Bad ELF format\n");
+ }
+ if (addr[4] != 2) {
+ die("64-bit format is mandatory\n");
+ }
+ if (addr[5] != 1) {
+ die("Little-endian only\n");
+ }
+}
+
+struct exec_header {
+ uint64_t e_entry;
+ uint64_t e_phoff;
+ uint16_t e_phnum;
+ uint16_t e_phentsize;
+};
+
+// TODO
+__kernel void extract_elf(int task_id, const unsigned char *const addr, size_t size)
{
__unused(task_id);
- __unused(addr);
__unused(size);
- // TODO
+ ensure_elf_format(addr);
+
+ /* struct exec_header header = { */
+ /* .e_entry = (unsigned long long)addr[0x18], */
+ /* .e_phoff = (uint64_t)addr[0x20], */
+ /* .e_phentsize = (uint16_t)addr[0x36], */
+ /* .e_phnum = (uint16_t)addr[0x38], */
+ /* }; */
+
+#ifdef __KERNEL__
+ tasks[task_id].addr = (const void *)addr;
+ tasks[task_id].entry_offset = (uint64_t)addr[0x18];
+#endif
}
-__kernel void extract_initrd(const char *const initrd_addr, uint64_t size)
+__kernel void extract_initrd(const unsigned char *const initrd_addr, uint64_t size)
{
char buffer[BUFFER_SIZE];
uint64_t name_size, file_size, padding, base = 0;
diff --git a/kernel/main.c b/kernel/main.c
index 7eb2ef6..089614f 100644
--- a/kernel/main.c
+++ b/kernel/main.c
@@ -4,9 +4,14 @@
#include <fbos/sched.h>
#include <fbos/dt.h>
-unsigned long init_stack[THREAD_SIZE / sizeof(unsigned long)];
+unsigned long init_stack[4][THREAD_SIZE / sizeof(unsigned long)];
-struct task_struct init_task = { .stack = init_stack };
+struct task_struct tasks[4] = {
+ [0] = { .stack = init_stack[0] },
+ [1] = { .stack = init_stack[1] },
+ [2] = { .stack = init_stack[2] },
+ [3] = { .stack = init_stack[3] },
+};
/*
* This is the main entry point of the kernel after head.S is done. This
@@ -21,7 +26,11 @@ __noreturn __kernel void start_kernel(void *dtb)
struct initrd_addr addr = find_dt_initrd_addr(dtb);
- extract_initrd((char *)addr.start, addr.end - addr.start);
+ extract_initrd((unsigned char *)addr.start, addr.end - addr.start);
+
+ // TODO: this is the jump address for the first task.
+ const char *ddr = (const char *)tasks[1].addr + tasks[1].entry_offset;
+ __unused(ddr);
// TODO: reenable stuff
diff --git a/test/test_initrd.c b/test/test_initrd.c
index 3662eaa..73429b8 100644
--- a/test/test_initrd.c
+++ b/test/test_initrd.c
@@ -3,6 +3,17 @@
#include <assert.h>
#include <fbos/init.h>
+#include <fbos/sched.h>
+#include <fbos/mm.h>
+
+unsigned long init_stack[4][THREAD_SIZE / sizeof(unsigned long)];
+
+struct task_struct tasks[4] = {
+ [0] = { .stack = init_stack[0] },
+ [1] = { .stack = init_stack[1] },
+ [2] = { .stack = init_stack[2] },
+ [3] = { .stack = init_stack[3] },
+};
int main(void)
{
@@ -13,7 +24,7 @@ int main(void)
long fsize = ftell(fh);
rewind(fh);
- char *contents = malloc((unsigned long)fsize + 1);
+ unsigned char *contents = malloc((unsigned long)fsize + 1);
fread(contents, (unsigned long)fsize, 1, fh);
fclose(fh);
diff --git a/usr/src/bar.S b/usr/src/bar.S
index 09c68e3..ee86b3e 100644
--- a/usr/src/bar.S
+++ b/usr/src/bar.S
@@ -2,8 +2,8 @@
.text
_start:
- li a0, 1
- la a1, bar
+ li a7, 1
+ la a0, bar
ecall
.Loop:
j .Loop
diff --git a/usr/src/foo.S b/usr/src/foo.S
index 57e82a1..c26b550 100644
--- a/usr/src/foo.S
+++ b/usr/src/foo.S
@@ -2,8 +2,8 @@
.text
_start:
- li a0, 1
- la a1, foo
+ li a7, 1
+ la a0, foo
ecall
.Loop:
j .Loop
diff --git a/usr/src/foobar.S b/usr/src/foobar.S
index 49c9e1d..e3fecb8 100644
--- a/usr/src/foobar.S
+++ b/usr/src/foobar.S
@@ -2,8 +2,8 @@
.text
_start:
- li a0, 1
- la a1, foobar
+ li a7, 1
+ la a0, foobar
ecall
.Loop:
j .Loop