mirror of
https://github.com/Zeal-Operating-System/ZealOS.git
synced 2024-12-26 15:26:43 +00:00
Initial work on ZealBooter
This commit is contained in:
parent
12201e46b6
commit
69f0f37b9b
7 changed files with 224 additions and 9 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -3,4 +3,6 @@
|
||||||
*.MAP
|
*.MAP
|
||||||
src/Boot/
|
src/Boot/
|
||||||
docs/Boot/
|
docs/Boot/
|
||||||
|
build/limine
|
||||||
|
build/ovmf
|
||||||
ZealOS-*.iso
|
ZealOS-*.iso
|
||||||
|
|
|
@ -35,6 +35,9 @@ umount_tempdisk() {
|
||||||
|
|
||||||
[ ! -d $TMPMOUNT ] && mkdir -p $TMPMOUNT
|
[ ! -d $TMPMOUNT ] && mkdir -p $TMPMOUNT
|
||||||
|
|
||||||
|
echo "Building ZealBooter..."
|
||||||
|
( cd ../zealbooter && make clean all )
|
||||||
|
|
||||||
echo "Making temp vdisk, running auto-install..."
|
echo "Making temp vdisk, running auto-install..."
|
||||||
qemu-img create -f raw $TMPDISK 192M
|
qemu-img create -f raw $TMPDISK 192M
|
||||||
qemu-system-x86_64 -machine q35,accel=kvm -drive format=raw,file=$TMPDISK -m 1G -rtc base=localtime -cdrom AUTO-VM-1.ISO -device isa-debug-exit
|
qemu-system-x86_64 -machine q35,accel=kvm -drive format=raw,file=$TMPDISK -m 1G -rtc base=localtime -cdrom AUTO-VM-1.ISO -device isa-debug-exit
|
||||||
|
@ -47,21 +50,25 @@ sudo cp -r ../src/* $TMPMOUNT
|
||||||
[ ! -d "limine" ] && git clone https://github.com/limine-bootloader/limine.git --branch=v3.0-branch-binary --depth=1
|
[ ! -d "limine" ] && git clone https://github.com/limine-bootloader/limine.git --branch=v3.0-branch-binary --depth=1
|
||||||
sudo mkdir -p $TMPMOUNT/EFI/BOOT
|
sudo mkdir -p $TMPMOUNT/EFI/BOOT
|
||||||
sudo cp limine/BOOTX64.EFI $TMPMOUNT/EFI/BOOT/BOOTX64.EFI
|
sudo cp limine/BOOTX64.EFI $TMPMOUNT/EFI/BOOT/BOOTX64.EFI
|
||||||
|
sudo cp ../zealbooter/zealbooter.elf $TMPMOUNT/Boot/ZealBooter.ELF
|
||||||
umount_tempdisk
|
umount_tempdisk
|
||||||
|
|
||||||
#echo "Generating ISO..."
|
echo "Rebuilding kernel..."
|
||||||
echo "Running temporary VM"
|
|
||||||
qemu-system-x86_64 -machine q35,accel=kvm -drive format=raw,file=$TMPDISK -m 1G -rtc base=localtime -device isa-debug-exit
|
qemu-system-x86_64 -machine q35,accel=kvm -drive format=raw,file=$TMPDISK -m 1G -rtc base=localtime -device isa-debug-exit
|
||||||
qemu-system-x86_64 -machine q35,accel=kvm -drive format=raw,file=$TMPDISK -m 1G -rtc base=localtime -bios /usr/share/ovmf/OVMF.fd
|
|
||||||
|
|
||||||
#echo "Extracting ISO from vdisk..."
|
if [ ! -d "ovmf" ]; then
|
||||||
#rm ./ZealOS-*.iso 2> /dev/null # comment this line if you want lingering old ISOs
|
echo "Downloading OVMF..."
|
||||||
#mount_tempdisk
|
mkdir ovmf
|
||||||
#cp $TMPMOUNT/Tmp/MyDistro.ISO.C ./ZealOS-$(date +%Y-%m-%d-%H_%M_%S).iso
|
cd ovmf
|
||||||
#umount_tempdisk
|
curl -o OVMF-X64.zip https://efi.akeo.ie/OVMF/OVMF-X64.zip
|
||||||
|
7z x OVMF-X64.zip
|
||||||
|
cd ..
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Testing..."
|
||||||
|
qemu-system-x86_64 -machine q35,accel=kvm -drive format=raw,file=$TMPDISK -m 1G -rtc base=localtime -bios ovmf/OVMF.fd
|
||||||
|
|
||||||
echo "Deleting temp folder..."
|
echo "Deleting temp folder..."
|
||||||
rm -rf $TMPDIR
|
rm -rf $TMPDIR
|
||||||
echo "Finished."
|
echo "Finished."
|
||||||
#ls -lh ZealOS-*.iso
|
|
||||||
|
|
||||||
|
|
6
src/limine.cfg
Normal file
6
src/limine.cfg
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
TIMEOUT=2
|
||||||
|
|
||||||
|
:ZealOS
|
||||||
|
PROTOCOL=limine
|
||||||
|
KERNEL_PATH=boot:///Boot/ZealBooter.ELF
|
||||||
|
MODULE_PATH=boot:///Boot/Kernel.ZXE
|
6
zealbooter/.gitignore
vendored
Normal file
6
zealbooter/.gitignore
vendored
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
limine.h
|
||||||
|
*.elf
|
||||||
|
*.iso
|
||||||
|
*.hdd
|
||||||
|
*.o
|
||||||
|
*.d
|
106
zealbooter/GNUmakefile
Normal file
106
zealbooter/GNUmakefile
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
# This is the name that our final kernel executable will have.
|
||||||
|
# Change as needed.
|
||||||
|
override KERNEL := zealbooter.elf
|
||||||
|
|
||||||
|
# Convenience macro to reliably declare overridable command variables.
|
||||||
|
define DEFAULT_VAR =
|
||||||
|
ifeq ($(origin $1), default)
|
||||||
|
override $(1) := $(2)
|
||||||
|
endif
|
||||||
|
ifeq ($(origin $1), undefined)
|
||||||
|
override $(1) := $(2)
|
||||||
|
endif
|
||||||
|
endef
|
||||||
|
|
||||||
|
# It is highly recommended to use a custom built cross toolchain to build a kernel.
|
||||||
|
# We are only using "cc" as a placeholder here. It may work by using
|
||||||
|
# the host system's toolchain, but this is not guaranteed.
|
||||||
|
$(eval $(call DEFAULT_VAR,CC,cc))
|
||||||
|
|
||||||
|
# Same thing for "ld" (the linker).
|
||||||
|
$(eval $(call DEFAULT_VAR,LD,ld))
|
||||||
|
|
||||||
|
# User controllable CFLAGS.
|
||||||
|
CFLAGS ?= -O2 -g -Wall -Wextra -Wpedantic -pipe
|
||||||
|
|
||||||
|
# User controllable preprocessor flags. We set none by default.
|
||||||
|
CPPFLAGS ?=
|
||||||
|
|
||||||
|
# User controllable nasm flags.
|
||||||
|
NASMFLAGS ?= -F dwarf -g
|
||||||
|
|
||||||
|
# User controllable linker flags. We set none by default.
|
||||||
|
LDFLAGS ?=
|
||||||
|
|
||||||
|
# Internal C flags that should not be changed by the user.
|
||||||
|
override CFLAGS += \
|
||||||
|
-I. \
|
||||||
|
-std=c11 \
|
||||||
|
-ffreestanding \
|
||||||
|
-fno-stack-protector \
|
||||||
|
-fno-stack-check \
|
||||||
|
-fno-pie \
|
||||||
|
-fno-pic \
|
||||||
|
-m64 \
|
||||||
|
-march=x86-64 \
|
||||||
|
-mabi=sysv \
|
||||||
|
-mno-80387 \
|
||||||
|
-mno-mmx \
|
||||||
|
-mno-sse \
|
||||||
|
-mno-sse2 \
|
||||||
|
-mno-red-zone \
|
||||||
|
-mcmodel=kernel \
|
||||||
|
-MMD
|
||||||
|
|
||||||
|
# Internal linker flags that should not be changed by the user.
|
||||||
|
override LDFLAGS += \
|
||||||
|
-nostdlib \
|
||||||
|
-static \
|
||||||
|
-z max-page-size=0x1000 \
|
||||||
|
-T linker.ld
|
||||||
|
|
||||||
|
# Internal nasm flags that should not be changed by the user.
|
||||||
|
override NASMFLAGS += \
|
||||||
|
-f elf64
|
||||||
|
|
||||||
|
# Use find to glob all *.c, *.S, and *.asm files in the directory and extract the object names.
|
||||||
|
override CFILES := $(shell find ./ -type f -name '*.c')
|
||||||
|
override ASFILES := $(shell find ./ -type f -name '*.S')
|
||||||
|
override NASMFILES := $(shell find ./ -type f -name '*.asm')
|
||||||
|
override OBJ := $(CFILES:.c=.o) $(ASFILES:.S=.o) $(NASMFILES:.asm=.o)
|
||||||
|
override HEADER_DEPS := $(CFILES:.c=.d) $(ASFILES:.S=.d)
|
||||||
|
|
||||||
|
# Default target.
|
||||||
|
.PHONY: all
|
||||||
|
all: $(KERNEL)
|
||||||
|
|
||||||
|
limine.h:
|
||||||
|
curl https://raw.githubusercontent.com/limine-bootloader/limine/trunk/limine.h -o $@
|
||||||
|
|
||||||
|
# Link rules for the final kernel executable.
|
||||||
|
$(KERNEL): $(OBJ)
|
||||||
|
$(LD) $(OBJ) $(LDFLAGS) -o $@
|
||||||
|
|
||||||
|
# Include header dependencies.
|
||||||
|
-include $(HEADER_DEPS)
|
||||||
|
|
||||||
|
# Compilation rules for *.c files.
|
||||||
|
%.o: %.c limine.h
|
||||||
|
$(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
# Compilation rules for *.S files.
|
||||||
|
%.o: %.S limine.h
|
||||||
|
$(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
# Compilation rules for *.asm (nasm) files.
|
||||||
|
%.o: %.asm
|
||||||
|
nasm $(NASMFLAGS) $< -o $@
|
||||||
|
|
||||||
|
# Remove object files and the final executable.
|
||||||
|
.PHONY: clean
|
||||||
|
clean:
|
||||||
|
rm -rf $(KERNEL) $(OBJ) $(HEADER_DEPS)
|
||||||
|
|
||||||
|
.PHONY: distclean
|
||||||
|
distclean: clean
|
||||||
|
rm -f limine.h
|
53
zealbooter/linker.ld
Normal file
53
zealbooter/linker.ld
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
/* Tell the linker that we want an x86_64 ELF64 output file */
|
||||||
|
OUTPUT_FORMAT(elf64-x86-64)
|
||||||
|
OUTPUT_ARCH(i386:x86-64)
|
||||||
|
|
||||||
|
/* We want the symbol _start to be our entry point */
|
||||||
|
ENTRY(_start)
|
||||||
|
|
||||||
|
/* Define the program headers we want so the bootloader gives us the right */
|
||||||
|
/* MMU permissions */
|
||||||
|
PHDRS
|
||||||
|
{
|
||||||
|
text PT_LOAD FLAGS((1 << 0) | (1 << 2)) ; /* Execute + Read */
|
||||||
|
rodata PT_LOAD FLAGS((1 << 2)) ; /* Read only */
|
||||||
|
data PT_LOAD FLAGS((1 << 1) | (1 << 2)) ; /* Write + Read */
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
/* We wanna be placed in the topmost 2GiB of the address space, for optimisations */
|
||||||
|
/* and because that is what the Limine spec mandates. */
|
||||||
|
/* Any address in this region will do, but often 0xffffffff80000000 is chosen as */
|
||||||
|
/* that is the beginning of the region. */
|
||||||
|
. = 0xffffffff80000000;
|
||||||
|
|
||||||
|
.text : {
|
||||||
|
*(.text .text.*)
|
||||||
|
} :text
|
||||||
|
|
||||||
|
/* Move to the next memory page for .rodata */
|
||||||
|
. += CONSTANT(MAXPAGESIZE);
|
||||||
|
|
||||||
|
.rodata : {
|
||||||
|
*(.rodata .rodata.*)
|
||||||
|
} :rodata
|
||||||
|
|
||||||
|
/* Move to the next memory page for .data */
|
||||||
|
. += CONSTANT(MAXPAGESIZE);
|
||||||
|
|
||||||
|
.data : {
|
||||||
|
*(.data .data.*)
|
||||||
|
} :data
|
||||||
|
|
||||||
|
.bss : {
|
||||||
|
*(COMMON)
|
||||||
|
*(.bss .bss.*)
|
||||||
|
} :data
|
||||||
|
|
||||||
|
/* Discard .note.* and .eh_frame since they may cause issues on some hosts. */
|
||||||
|
/DISCARD/ : {
|
||||||
|
*(.eh_frame)
|
||||||
|
*(.note .note.*)
|
||||||
|
}
|
||||||
|
}
|
35
zealbooter/zealbooter.c
Normal file
35
zealbooter/zealbooter.c
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <limine.h>
|
||||||
|
|
||||||
|
// The Limine requests can be placed anywhere, but it is important that
|
||||||
|
// the compiler does not optimise them away, so, usually, they should
|
||||||
|
// be made volatile or equivalent.
|
||||||
|
|
||||||
|
static volatile struct limine_terminal_request terminal_request = {
|
||||||
|
.id = LIMINE_TERMINAL_REQUEST,
|
||||||
|
.revision = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
static void done(void) {
|
||||||
|
for (;;) {
|
||||||
|
__asm__("hlt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The following will be our kernel's entry point.
|
||||||
|
void _start(void) {
|
||||||
|
// Ensure we got a terminal
|
||||||
|
if (terminal_request.response == NULL
|
||||||
|
|| terminal_request.response->terminal_count < 1) {
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
|
||||||
|
// We should now be able to call the Limine terminal to print out
|
||||||
|
// a simple "Hello World" to screen.
|
||||||
|
struct limine_terminal *terminal = terminal_request.response->terminals[0];
|
||||||
|
terminal_request.response->write(terminal, "Hello World", 11);
|
||||||
|
|
||||||
|
// We're done, just hang...
|
||||||
|
done();
|
||||||
|
}
|
Loading…
Reference in a new issue