Skip to content

Commit 9dfc59c

Browse files
authored
Add and inject initramfs and a sample hello world program (#10)
* Add a sample 'hello' program * Add user makefile * Build user binaries and initramfs * Copy generated initramfs into iso * Add initramfs as a module * Add request for module * Check for initramfs being loaded into memory * Some print statement improvements
1 parent e2623a3 commit 9dfc59c

8 files changed

Lines changed: 173 additions & 5 deletions

File tree

Makefile

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,28 @@
1-
.PHONY: all kernel clean format
1+
.PHONY: all kernel clean format user initramfs
22

3-
all: kernel
3+
all: kernel user initramfs
44

55
kernel:
66
@echo "Building Kernel..."
77
$(MAKE) -C kernel
88

9+
user: user_bin
10+
11+
user_bin:
12+
@echo "Building user binaries..."
13+
$(MAKE) -C user bin
14+
15+
initramfs: user
16+
( cd build/initramfs && find . -print | cpio -o -H newc -v ) > build/initramfs.cpio
17+
918
format:
1019
@echo "Formatting Kernel..."
1120
$(MAKE) -C kernel format
21+
@echo "Formatting User..."
22+
$(MAKE) -C user format
1223

1324
clean:
1425
@echo "Cleaning Kernel..."
1526
$(MAKE) -C kernel clean
27+
@echo "Cleaning User..."
28+
$(MAKE) -C user clean

build.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ mkdir -p iso_root/boot/limine
131131
# Copy the relevant files over.
132132
cp -v limine.conf limine/limine-bios.sys limine/limine-bios-cd.bin limine/limine-uefi-cd.bin iso_root/boot/limine/
133133
cp -v build/kernel/entry.elf iso_root/boot/
134+
cp -v build/initramfs.cpio iso_root/boot/
134135

135136
# Create the EFI boot tree and copy Limine's EFI executables over.
136137
mkdir -p iso_root/EFI/BOOT

kernel/src/kernel/entry.c

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ extern volatile struct limine_framebuffer_request framebuffer_request;
2222
extern volatile struct limine_bootloader_info_request bootinfo_req;
2323
extern volatile struct limine_boot_time_request boottime_req;
2424
extern volatile struct limine_memmap_request memmap_req;
25+
extern volatile struct limine_module_request mod_req;
2526
extern volatile struct limine_hhdm_request hhdm_req;
2627

2728
uint64_t hhdm_base = 0;
@@ -133,14 +134,25 @@ void _start (void) {
133134
__asm__ volatile ("mov %%cr3, %0" : "=r"(cr3));
134135
cr3 = cr3 & 0xFFFFFFFFFF000;
135136

136-
printf ("CR3: %lx", cr3);
137+
printf ("CR3: %lx\n", cr3);
138+
139+
if (mod_req.response == NULL || mod_req.response->module_count < 1) {
140+
printf ("Error: no modules loaded.\n");
141+
hcf ();
142+
}
143+
144+
struct limine_file* initramfs = mod_req.response->modules[0];
145+
void* initramfs_addr = initramfs->address;
146+
uint64_t initramfs_size = initramfs->size;
147+
148+
printf ("\nInitramfs at 0x%llx, size %ld bytes\n", initramfs_addr, initramfs_size);
137149

138150
printf ("\nJumping to user land!\n");
139151

140152
/*
141153
* TODO: bunch of stuff
142-
* - [ ] set up user mode code to actually compile
143-
* - [ ] set up limine loading it as a module
154+
* - [x] set up user mode code to actually compile
155+
* - [x] set up limine loading it as a module
144156
* - [ ] set up a vfs
145157
* - [ ] set up elf-loading
146158
* - [ ] set up cpio reading and ramfs driver

kernel/src/kernel/limine_requests.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ __attribute__ ((used,
2020
section (".limine_requests"))) volatile struct limine_hhdm_request hhdm_req = {
2121
.id = LIMINE_HHDM_REQUEST, .revision = 0};
2222

23+
__attribute__ ((used,
24+
section (".limine_requests"))) volatile struct limine_module_request mod_req = {
25+
.id = LIMINE_MODULE_REQUEST, .revision = 0};
26+
2327
__attribute__ ((used,
2428
section (".limine_requests_start"))) static volatile LIMINE_REQUESTS_START_MARKER;
2529

limine.conf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ timeout: 2
44

55
protocol: limine
66
kernel_path: boot():/boot/entry.elf
7+
module_path: boot():/boot/initramfs.cpio

user/Makefile

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
.PHONY: all hello
2+
3+
all: hello
4+
5+
bin: hello
6+
7+
hello:
8+
@echo "Building hello..."
9+
$(MAKE) -C hello
10+
11+
format:
12+
@echo "Formatting hello..."
13+
$(MAKE) -C hello format
14+
15+
clean:
16+
@echo "Cleaning hello..."
17+
$(MAKE) -C hello clean

user/hello/Makefile

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
# This makefile is quite similar to the one used by the kernel, with
2+
# the exception of some kernel-only flags that have been omitted here
3+
4+
override MAKEFLAGS += -rR
5+
override TARGET := hello
6+
7+
define DEFAULT_VAR =
8+
ifeq ($(origin $1),default)
9+
override $(1) := $(2)
10+
endif
11+
ifeq ($(origin $1),undefined)
12+
override $(1) := $(2)
13+
endif
14+
endef
15+
16+
override DEFAULT_CC := x86_64-elf-gcc
17+
$(eval $(call DEFAULT_VAR,CC,$(DEFAULT_CC)))
18+
19+
override DEFAULT_LD := x86_64-elf-ld
20+
$(eval $(call DEFAULT_VAR,LD,$(DEFAULT_LD)))
21+
22+
override DEFAULT_CFLAGS := -g -O2 -pipe
23+
$(eval $(call DEFAULT_VAR,CFLAGS,$(DEFAULT_CFLAGS)))
24+
25+
# User controllable C preprocessor flags. We set none by default.
26+
override DEFAULT_CPPFLAGS :=
27+
$(eval $(call DEFAULT_VAR,CPPFLAGS,$(DEFAULT_CPPFLAGS)))
28+
29+
# User controllable linker flags. We set none by default.
30+
override DEFAULT_LDFLAGS :=
31+
$(eval $(call DEFAULT_VAR,LDFLAGS,$(DEFAULT_LDFLAGS)))
32+
33+
# Internal C flags that should not be changed by the user.
34+
override CFLAGS += \
35+
-Wall \
36+
-Wextra \
37+
-std=gnu11 \
38+
-ffreestanding \
39+
-fno-stack-protector \
40+
-fno-stack-check \
41+
-fno-lto \
42+
-fno-PIE \
43+
-fno-PIC \
44+
-m64 \
45+
-march=x86-64 \
46+
-mabi=sysv
47+
48+
# Internal C preprocessor flags that should not be changed by the user.
49+
override CPPFLAGS := \
50+
-I include \
51+
-I. \
52+
$(CPPFLAGS) \
53+
-MMD \
54+
-MP
55+
56+
# Internal linker flags that should not be changed by the user.
57+
override LDFLAGS += \
58+
-nostdlib \
59+
-static \
60+
-m elf_x86_64 \
61+
-z max-page-size=0x1000
62+
63+
ifeq ($(shell $(LD) --help 2>&1 | grep 'no-pie' >/dev/null 2>&1; echo $$?),0)
64+
override LDFLAGS += -no-pie
65+
endif
66+
67+
override CFILES := $(shell find -L . -type f -name '*.c')
68+
override ASFILES := $(shell find -L . -type f -name '*.s')
69+
70+
override BUILD_DIR := ../../build/user/bin
71+
override INITRAMFS_DIR := ../../build/initramfs/bin
72+
73+
override OBJ := $(patsubst %.c,$(BUILD_DIR)/%.c.o,$(CFILES)) $(patsubst %.s,$(BUILD_DIR)/%.s.o,$(ASFILES))
74+
override HEADER_DEPS := $(patsubst %.c,$(BUILD_DIR)/%.c.d,$(CFILES)) $(patsubst %.s,$(BUILD_DIR)/%.s.d,$(ASFILES))
75+
76+
.PHONY: all
77+
all: $(BUILD_DIR)/$(TARGET)
78+
79+
$(BUILD_DIR)/$(TARGET): $(OBJ)
80+
$(LD) $(OBJ) $(LDFLAGS) -o $@
81+
@mkdir -p $(INITRAMFS_DIR)
82+
@cp $(BUILD_DIR)/$(TARGET) $(INITRAMFS_DIR)
83+
84+
-include $(HEADER_DEPS)
85+
86+
$(BUILD_DIR)/%.c.o: %.c
87+
@mkdir -p $(@D)
88+
$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@
89+
90+
$(BUILD_DIR)/%.s.o: %.s
91+
@mkdir -p $(@D)
92+
$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@
93+
94+
.PHONY: clean
95+
clean:
96+
rm -rf $(BUILD_DIR)
97+
98+
.PHONY: format
99+
format:
100+
find -type f \( -name '*.c' -o -name '*.h' \) ! -name 'limine.h' -exec clang-format -i {} +

user/hello/hello.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
2+
static inline long syscall3 (long num, long arg1, long arg2, long arg3) {
3+
long ret;
4+
__asm__ volatile ("int $0x80"
5+
: "=a"(ret)
6+
: "a"(num), "b"(arg1), "c"(arg2), "d"(arg3)
7+
: "memory");
8+
return ret;
9+
}
10+
11+
void _start (void) {
12+
const char* msg = "Hello world!\n";
13+
14+
syscall3 (4, 1, (long)msg, 13);
15+
syscall3 (1, 0, 0, 0);
16+
17+
while (1) {
18+
__asm__ volatile ("pause");
19+
}
20+
}

0 commit comments

Comments
 (0)