diff options
| author | Miquel Sabaté Solà <mikisabate@gmail.com> | 2024-11-18 15:56:37 +0100 |
|---|---|---|
| committer | Miquel Sabaté Solà <mikisabate@gmail.com> | 2024-11-18 15:56:37 +0100 |
| commit | d79436a1170e4d5ffde77416313587f320c8e590 (patch) | |
| tree | cc3bc766e912f757b0244d986519cd6bb49b3bf6 | |
| parent | 54cf703d13bddbe81e15858b1bfdb7111a3f56de (diff) | |
| download | fbos-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-- | .gitignore | 2 | ||||
| -rw-r--r-- | Makefile | 49 | ||||
| -rw-r--r-- | README.md | 5 | ||||
| -rw-r--r-- | usr/src/foo.S | 13 |
4 files changed, 57 insertions, 12 deletions
@@ -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 @@ -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: @@ -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" |
