diff options
| -rw-r--r-- | Makefile | 24 | ||||
| -rw-r--r-- | kernel/riscv/header.S | 23 | ||||
| -rw-r--r-- | kernel/riscv/linker.ld | 13 | ||||
| -rw-r--r-- | misc/kassemble.c | 47 |
4 files changed, 103 insertions, 4 deletions
@@ -2,6 +2,7 @@ VERSION = 0.1.0-alpha CC = clang LD = ld.lld +NM = llvm-nm OBJCOPY = llvm-objcopy COMPILER = $(shell $(CC) --version | head -n 1) @@ -99,20 +100,27 @@ KERNEL_OBJS = $(KERNEL_SRCS:.c=.o) KERNEL_OBJS := $(KERNEL_OBJS:.S=.o) KERNEL_BIN := $(KERNEL_TARGET)/kernel.bin KERNEL_ELF := $(KERNEL_TARGET)/kernel.elf +KERNEL_IMAGE := $(KERNEL_TARGET)/Image + +KASSEMBLE_BIN := misc/kassemble +KASSEMBLE_SRC := misc/kassemble.c GENERATED = \ $(KERNEL_OBJS) \ $(KERNEL_ELF) \ $(KERNEL_BIN) \ + $(KERNEL_IMAGE) \ $(foreach m,$(MODULES),$(m)/$(m).elf) \ $(foreach m,$(MODULES),$(m)/$(m).ko) \ - $(foreach m,$(MODULES),$($(m)_OBJS)) + $(foreach m,$(MODULES),$($(m)_OBJS)) \ + $(KASSEMBLE_BIN) -.PHONY: all kernel clean modules $(MODULES) +.PHONY: all kernel kassemble clean modules $(MODULES) $(V).SILENT: -all: kernel modules -kernel: $(KERNEL_BIN) +all: kassemble kernel modules +kernel: $(KERNEL_IMAGE) modules: $(MODULES) +kassemble: $(KASSEMBLE_BIN) $(MODULES): $(MODULE_OBJECTS) %.o: %.c @@ -122,6 +130,10 @@ $(MODULES): $(MODULE_OBJECTS) @echo " AS $<" $(CC) $(KERNEL_CFLAGS) -c $< -o $@ +$(KASSEMBLE_BIN): $(KASSEMBLE_SRC) + @echo " HOSTCC $<" + $(CC) -O2 $< -o $@ + $(KERNEL_ELF): $(KERNEL_OBJS) $(KERNEL_LD) | $(KERNEL_OUTDIR)/ @echo " LD $@" $(LD) $(KERNEL_LD_FLAG) $(KERNEL_OBJS) -o $@ @@ -130,6 +142,10 @@ $(KERNEL_BIN): $(KERNEL_ELF) | $(KERNEL_OUTDIR)/ @echo " OBJCOPY $@" $(OBJCOPY) $(KERNEL_OBJCOPY_FLAG) $(KERNEL_ELF) $(KERNEL_BIN) +$(KERNEL_IMAGE): $(KERNEL_BIN) | $(KERNEL_OUTDIR)/ + @echo " KASSEMBLE $@" + $(KASSEMBLE_BIN) $< $@ $$($(NM) $(KERNEL_ELF) | awk '/__image_size/{print $$1}') + clean: @echo " CLEAN $(GENERATED)" $(RM) $(GENERATED) diff --git a/kernel/riscv/header.S b/kernel/riscv/header.S new file mode 100644 index 0000000..cca2594 --- /dev/null +++ b/kernel/riscv/header.S @@ -0,0 +1,23 @@ +.section .header, "a", @progbits +.extern _start +#define CODE0 0x4d, 0x5a, 0, 0 +#define FLAGS 0 +#define TEXT_OFFSET 0 +#define HEADER_VERSION 0x00000002 +#define RES1 0 +#define RES2 0 +#define RES3 0 +#define MAGIC 0x5643534952 +#define MAGIC2 0x05435352 +header: + .byte CODE0 + j _start + .quad TEXT_OFFSET + .quad 0 # image_size + .quad FLAGS + .int HEADER_VERSION + .int RES1 + .quad RES2 + .quad MAGIC + .int MAGIC2 + .int RES3 diff --git a/kernel/riscv/linker.ld b/kernel/riscv/linker.ld index ec51176..6689dce 100644 --- a/kernel/riscv/linker.ld +++ b/kernel/riscv/linker.ld @@ -10,6 +10,11 @@ MEMORY SECTIONS { + .header : { + KEEP(*(.header)) + *(.header) + } > ROM + .text : { KEEP(*(.text._start)) KEEP(*(.text.start)) @@ -60,6 +65,11 @@ SECTIONS __ringbuf_end = .; } > LOGRAM + .image_end (NOLOAD) : { + . = ALIGN(4); + __image_end = .; + } > ROM + /DISCARD/ : { *(.eh_frame) *(.eh_frame.*) @@ -71,4 +81,7 @@ SECTIONS *(.llvm_*) *(.rela.*) } + + __image_start = ORIGIN(ROM); + __image_size = __image_end - __image_start; } diff --git a/misc/kassemble.c b/misc/kassemble.c new file mode 100644 index 0000000..a818cc5 --- /dev/null +++ b/misc/kassemble.c @@ -0,0 +1,47 @@ +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <errno.h> + +int main(int argc, char **argv) { + if (argc != 4) { + fprintf(stderr, "usage: %s <in> <out> <image_size>\n", argv[0]); + return 1; + } + + const char *in_path = argv[1]; + const char *out_path = argv[2]; + char *end; + errno = 0; + unsigned long long size = strtoull(argv[3], &end, 16); + if (errno || *end != '\0') { + fprintf(stderr, "bad size: %s, invalid chars: %s\n", argv[3], end); + return 1; + } + + FILE *in = fopen(in_path, "rb"); + if (!in) { perror("fopen in"); return 1; } + + FILE *out = fopen(out_path, "wb"); + if (!out) { perror("fopen out"); fclose(in); return 1; } + + /* Copy in -> out */ + unsigned char buf[65536]; + size_t n; + while ((n = fread(buf, 1, sizeof buf, in)) > 0) { + if (fwrite(buf, 1, n, out) != n) { perror("fwrite"); return 1; } + } + if (ferror(in)) { perror("fread"); return 1; } + + /* Write size as u64 little-endian at offset 16 */ + unsigned char le[8]; + for (int i = 0; i < 8; i++) + le[i] = (unsigned char)(size >> (8 * i)); + + if (fseek(out, 16, SEEK_SET) != 0) { perror("fseek"); return 1; } + if (fwrite(le, 1, 8, out) != 8) { perror("fwrite size"); return 1; } + + fclose(in); + if (fclose(out) != 0) { perror("fclose out"); return 1; } + return 0; +} |
