aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiquel Sabaté Solà <mikisabate@gmail.com>2024-11-18 15:56:37 +0100
committerMiquel Sabaté Solà <mikisabate@gmail.com>2024-11-18 15:56:37 +0100
commitd79436a1170e4d5ffde77416313587f320c8e590 (patch)
treecc3bc766e912f757b0244d986519cd6bb49b3bf6
parent54cf703d13bddbe81e15858b1bfdb7111a3f56de (diff)
downloadfbos-d79436a1170e4d5ffde77416313587f320c8e590.tar.gz
fbos-d79436a1170e4d5ffde77416313587f320c8e590.zip
usr: Bootstrap the initramfs for the kernel
Introduce a sample `foo` program which already calls the `write_and_block` system call which is yet to be implemented by this kernel. Moreover, the same CPIO format is used for the initramfs as with Linux, so we can pass it with QEMU without worries. Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
-rw-r--r--.gitignore2
-rw-r--r--Makefile49
-rw-r--r--README.md5
-rw-r--r--usr/src/foo.S13
4 files changed, 57 insertions, 12 deletions
diff --git a/.gitignore b/.gitignore
index f1ccbff..d87610d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,6 +2,8 @@
kernel/fbos.ld
/fbos
.cache
+usr/bin/*
+usr/initramfs.cpio
# You can generate it with Bear: `$ bear -- make`.
compile_commands.json
diff --git a/Makefile b/Makefile
index df82342..6799281 100644
--- a/Makefile
+++ b/Makefile
@@ -18,15 +18,19 @@ endif
# no `-mcpu`, no `-mtune`, no funny business.
CC = $(CROSS_COMPILE)gcc$(CC_SUFFIX)
+AS = $(CROSS_COMPILE)as$(CC_SUFFIX)
LD = $(CROSS_COMPILE)ld
QEMU ?= qemu-system-riscv64
ISA ?= rv64imafdc_zicntr_zicsr_zifencei_zihpm_zca_zcd_zba_zbb
-CCFLAGS = -march=$(ISA) -Iinclude/ -mabi=lp64d
+ASFLAGS = -march=$(ISA) -mabi=lp64d
+CCFLAGS = $(ASFLAGS) -Iinclude/
CCFLAGS += -Werror -Wpedantic -Wall -Wextra -Wcast-align -Wcast-qual -Winit-self \
-Wmissing-include-dirs -Wredundant-decls -Wshadow -Wsign-conversion \
- -Wswitch-default -Wundef -Wunreachable-code -Wmissing-noreturn
-LDFLAGS = -Iinclude/ -static -nostdlib -melf64lriscv -z noexecstack
+ -Wswitch-default -Wundef -Wunreachable-code -Wmissing-noreturn \
+ -nostdinc -nostdlib -std=gnu17
+LDFLAGS = -Iinclude/ -static -melf64lriscv -z noexecstack
+USRFLAGS = -static -melf64lriscv
##
# Optional parameters for QEMU and gdb.
@@ -42,26 +46,29 @@ GDB_EXTRA_FLAGS ?=
DEBUG =
ifeq ($(strip $(DEBUG)),)
CCFLAGS += -O3
+ QEMU_FLAGS += -nographic
else
CCFLAGS += -g
QEMU_FLAGS += -s -S
endif
##
-# Paths.
+# Paths
SRC = $(wildcard kernel/head.S kernel/*.c)
OBJ = $(patsubst %.c,%.o,$(patsubst %.S,%.o,$(SRC)))
LINKER = kernel/fbos.ld
KRNL = fbos
+USR = usr/bin/foo
+INIT = usr/initramfs.cpio
LDFLAGS += -T $(LINKER)
##
-# Targets
+# Kernel
.PHONY: all
-all: clean $(KRNL)
+all: clean $(KRNL) usr
.PHONY: $(KRNL)
$(KRNL): $(OBJ) $(LINKER).S
@@ -78,12 +85,34 @@ $(KRNL): $(OBJ) $(LINKER).S
$(E) " CC " $(*F)
$(Q) $(CC) $(CCFLAGS) -c $< -o $@
+##
+# User space
+
+.PHONY: usr
+usr: $(USR)
+ $(E) " CPIO " $(INIT)
+ $(Q) find usr/bin/ -type f -executable | cpio -o --quiet -H newc > $(INIT)
+
+usr/src/%.o: usr/src/%.S
+ $(E) " AS " $(basename $@)
+ $(Q) $(AS) $(ASFLAGS) -c $< -o $@
+
+usr/bin/%: usr/src/%.o
+ $(E) " LD " $@
+ $(Q) $(LD) $(USRFLAGS) $< -o $@
+
+# HACK: do not remove object files from usr/src/.
+.SECONDARY:
+
+##
+# Hacking
+
.PHONY: qemu
-qemu: $(KRNL)
+qemu: $(KRNL) usr
ifeq ($(strip $(QEMU_BIOS)),)
- $(Q) $(QEMU) $(QEMU_FLAGS) -machine virt -kernel $(KRNL) -nographic
+ $(Q) $(QEMU) $(QEMU_FLAGS) -machine virt -kernel $(KRNL) -initrd $(INIT)
else
- $(Q) $(QEMU) $(QEMU_FLAGS) -machine virt -bios $(QEMU_BIOS) -kernel $(KRNL) -nographic
+ $(Q) $(QEMU) $(QEMU_FLAGS) -machine virt -bios $(QEMU_BIOS) -kernel $(KRNL) -initrd $(INIT)
endif
.PHONY: gdb
@@ -92,7 +121,7 @@ gdb:
.PHONY: clean
clean:
- $(Q) rm -f $(OBJ) $(KRNL) $(LINKER)
+ $(Q) rm -f $(OBJ) $(KRNL) $(LINKER) $(USR) usr/src/*.o $(INIT)
.PHONY: lint
lint:
diff --git a/README.md b/README.md
index 5833b55..8ce947f 100644
--- a/README.md
+++ b/README.md
@@ -8,8 +8,9 @@ are unaware of each other and it's up to the kernel to schedule them by using
the timer interrupts as given by openSBI (`fizz` on % 3 seconds, `buzz` on % 5
seconds, and `fizzbuzz` on % 15 seconds).
-This kernel provides just one system call, `write`, which allows any program to
-pass the string to be written into the serial port.
+This kernel provides just one system call, `write_and_block`, which allows any
+program to pass the string to be written into the serial port and wait for the
+kernel to re-schedule it.
## Build
diff --git a/usr/src/foo.S b/usr/src/foo.S
new file mode 100644
index 0000000..57e82a1
--- /dev/null
+++ b/usr/src/foo.S
@@ -0,0 +1,13 @@
+.global _start
+.text
+
+_start:
+ li a0, 1
+ la a1, foo
+ ecall
+.Loop:
+ j .Loop
+
+.section .rodata
+foo:
+ .string "foo\n"