Skip to content

Commit

Permalink
Fetch the initrd address from the DTB blob
Browse files Browse the repository at this point in the history
The kernel entry has a pointer to the DTB blob as a parameter. From this
pointer we can parse the the DTB blob to find the properties
"chosen->linux,initrd-start" and "chosen->linux,initrd-start". These
properties are guaranteed to have 64-bit addresses which point where the
initrd is in memory, which we need to fetch the binaries to be loaded.

Signed-off-by: Miquel Sabaté Solà <[email protected]>
  • Loading branch information
mssola committed Nov 20, 2024
1 parent d3afdd9 commit fb9627c
Show file tree
Hide file tree
Showing 14 changed files with 285 additions and 52 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@
kernel/fbos.ld
/fbos
.cache

usr/bin/*
usr/initramfs.cpio

test/*.o
test/test_dt

# You can generate it with Bear: `$ bear -- make`.
compile_commands.json
58 changes: 39 additions & 19 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,20 @@ endif
# I did not go too much into the rabbit hole of platform-specific flags. Hence
# no `-mcpu`, no `-mtune`, no funny business.

CC = $(CROSS_COMPILE)gcc$(CC_SUFFIX)
LD = $(CROSS_COMPILE)ld
CC = $(CROSS_COMPILE)gcc$(CC_SUFFIX)
LD = $(CROSS_COMPILE)ld
HOSTCC = gcc
QEMU ?= qemu-system-riscv64

ISA ?= rv64imafdc_zicntr_zicsr_zifencei_zihpm_zca_zcd_zba_zbb
ASFLAGS = -march=$(ISA) -mabi=lp64d -mcmodel=medany
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 \
-nostdinc -nostdlib -std=gnu17
LDFLAGS = -Iinclude/ -static -melf64lriscv -z noexecstack
USRFLAGS = -static -melf64lriscv
ISA ?= rv64imafdc_zicntr_zicsr_zifencei_zihpm_zca_zcd_zba_zbb
ASFLAGS = -march=$(ISA) -mabi=lp64d -mcmodel=medany
CCFLAGS = $(ASFLAGS) -Iinclude/ -D__KERNEL__ -std=gnu17 -nostdinc -nostdlib
WARNINGS = -Werror -Wpedantic -Wall -Wextra -Wcast-align -Wcast-qual -Winit-self \
-Wmissing-include-dirs -Wredundant-decls -Wshadow -Wsign-conversion \
-Wswitch-default -Wundef -Wunreachable-code
CCFLAGS += $(WARNINGS)
LDFLAGS = -Iinclude/ -static -melf64lriscv -z noexecstack
USRFLAGS = -static -melf64lriscv

##
# Optional parameters for QEMU and gdb.
Expand All @@ -55,20 +56,21 @@ endif
##
# Paths

SRC = $(filter-out kernel/fbos.ld.S, $(wildcard kernel/*.S kernel/*.c))
SRC = $(filter-out kernel/fbos.ld.S, $(wildcard kernel/*.S kernel/*.c lib/*.c))
OBJ = $(patsubst %.c,%.o,$(patsubst %.S,%.o,$(SRC)))
LINKER = kernel/fbos.ld
KRNL = fbos
USR = usr/bin/foo
INIT = usr/initramfs.cpio
TESTS = test/test_dt

LDFLAGS += -T $(LINKER)

##
# Kernel

.PHONY: all
all: clean $(KRNL) usr
all: clean $(KRNL) usr test

.PHONY: $(KRNL)
$(KRNL): $(OBJ) $(LINKER).S
Expand All @@ -78,12 +80,12 @@ $(KRNL): $(OBJ) $(LINKER).S
$(Q) $(LD) $(LDFLAGS) $(OBJ) -o $(KRNL)

.c.o:
$(E) " CC " $(*F)
$(Q) $(CC) $(CCFLAGS) -c $< -o $@
$(E) " CC " $(basename $@)
$(Q) $(CC) $(CCFLAGS) $(KRNLFLAGS) -c $< -o $@

.S.o:
$(E) " CC " $(*F)
$(Q) $(CC) $(CCFLAGS) -D__ASSEMBLY__ -c $< -o $@
$(E) " CC " $(basename $@)
$(Q) $(CC) $(CCFLAGS) -D__ASSEMBLY__ -D__KERNEL__ -c $< -o $@

##
# User space
Expand All @@ -95,7 +97,7 @@ usr: $(USR)

usr/src/%.o: usr/src/%.S
$(E) " CC " $(basename $@)
$(Q) $(CC) $(ASFLAGS) -D__ASSEMBLY__ -c $< -o $@
$(Q) $(CC) $(ASFLAGS) -D__ASSEMBLY__ -D__KERNEL__ -c $< -o $@

usr/bin/%: usr/src/%.o
$(Q) mkdir -p usr/bin/
Expand All @@ -105,6 +107,24 @@ usr/bin/%: usr/src/%.o
# HACK: do not remove object files from usr/src/.
.SECONDARY:

##
# Tests

.PHONY: test
test: host_lib $(TESTS)
$(Q) ./test/test_dt

host_lib:
$(Q) $(HOSTCC) $(WARNINGS) -Iinclude/ -g -c lib/dt.c -o lib/dt.o

test/%.o: test/%.c
$(E) " HOSTCC " $(basename $@)
$(Q) $(HOSTCC) $(WARNINGS) -g -Iinclude/ -c $< -o $@

test/%: test/%.o
$(E) " HOSTLD " $@
$(Q) $(HOSTCC) -Iinclude/ $< lib/dt.o -o $@

##
# Hacking

Expand All @@ -122,7 +142,7 @@ gdb:

.PHONY: clean
clean:
$(Q) rm -f $(OBJ) $(KRNL) $(LINKER) $(USR) usr/src/*.o $(INIT)
$(Q) rm -f $(OBJ) $(KRNL) $(LINKER) $(USR) usr/src/*.o $(INIT) test/*.o $(TESTS)

.PHONY: lint
lint:
Expand Down
12 changes: 11 additions & 1 deletion include/fbos/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,35 @@
* Compiler attributes specific to linker sections.
*/

#ifdef __KERNEL__
#define __section(s) __attribute__((__section__(s)))
#define __kernel __section(".kernel.text")
#else
#define __kernel
#endif /* __KERNEL__ */

/*
* Multiple aliases for 64-bit integers which have their definition on the
* Multiple aliases for 32/64-bit integers which have their definition on the
* standard library.
*/

typedef int int32_t;
typedef long ssize_t;
typedef long int64_t;

typedef unsigned long size_t;
typedef unsigned int uint32_t;
typedef unsigned long uint64_t;
typedef unsigned long uintptr_t;

/*
* NULL
*/

#ifdef __KERNEL__
#define NULL (void *)0
#define nullptr NULL
#endif /* __KERNEL__ */

// Helpful macro when prototyping.
#define __unused(x) (void)x
Expand Down
9 changes: 8 additions & 1 deletion include/fbos/dt.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@

#include <fbos/compiler.h>

void parse_dtb(uint64_t *dtb);
// Pair of addresses where the initrd is located in memory.
struct initrd_addr {
uintptr_t start;
uintptr_t end;
};

// Returns the `initrd` addresses as parsed from the given DTB blob.
struct initrd_addr find_dt_initrd_addr(uint32_t *dtb);

#endif // __FBOS_DT_H_
2 changes: 1 addition & 1 deletion include/fbos/init.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@
extern struct task_struct init_task;

// The entry point for the kernel.
__noreturn __kernel void start_kernel(uintptr_t *dtb);
__noreturn __kernel void start_kernel(void *dtb);

#endif /* __FBOS_INIT_H */
17 changes: 17 additions & 0 deletions include/fbos/printk.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,24 @@
#ifndef __FBOS_PRINTK_H_
#define __FBOS_PRINTK_H_

/*
* This file might be pulled from user space tests. Hence, define alternatives
* for this functions from glibc.
*/

#ifdef __KERNEL__
extern void die(const char *const message);
extern void printk(const char *const message);
#else
#include <stdio.h>
#include <stdlib.h>

#define die(x) \
do { \
printf(x); \
exit(1); \
} while (0)
#define printk(x) printf(x)
#endif /* __KERNEL */

#endif // __FBOS_PRINTK_H_
1 change: 1 addition & 0 deletions include/fbos/string.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@
#include <fbos/compiler.h>

extern size_t strlen(const char *);
extern int strcmp(const char *, const char *);

#endif // __FBOS_STRING_H_
6 changes: 0 additions & 6 deletions kernel/dt.c

This file was deleted.

5 changes: 3 additions & 2 deletions kernel/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,14 @@ struct task_struct init_task = { .stack = init_stack };
* function can (and will) assume that everything has been reset and that we can
* start the whole thing.
*/
__noreturn __kernel void start_kernel(uintptr_t *dtb)
__noreturn __kernel void start_kernel(void *dtb)
{
// TODO: disable irqs, etc.

printk("Welcome to FizzBuzz OS!\n");

parse_dtb(dtb);
struct initrd_addr addr = find_dt_initrd_addr(dtb);
__unused(addr); // TODO

// TODO: reenable stuff

Expand Down
46 changes: 46 additions & 0 deletions kernel/string.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Defined in include/fbos/string.h
*
* size_t strlen(const char *str)
*
* Returns (a0): string length.
* Parameter (a0): string to measure.
* Clobbers: t0, t1.
*/
.globl strlen
.type strlen, @function
strlen:
mv t1, a0
1:
lbu t0, 0(t1)
beqz t0, 2f
addi t1, t1, 1
j 1b
2:
sub a0, t1, a0
ret

/*
* Defined in include/fbos/string.h
*
* int strcmp(const char *s1, const char *s2)
*
* Returns (a0): comparison result as in stdlib.
* Parameter (a0, a1): strings to compare.
* Clobbers: t0, t1.
*/
.globl strcmp
.type strcmp, @function
strcmp:
1:
lbu t0, 0(a0)
lbu t1, 0(a1)
bne t0, t1, 2f
addi a0, a0, 1
addi a1, a1, 1
bnez t0, 1b
li a0, 0
ret
2:
sub a0, t0, t1
ret
22 changes: 0 additions & 22 deletions kernel/strlen.S

This file was deleted.

Loading

0 comments on commit fb9627c

Please sign in to comment.