diff --git a/.gitignore b/.gitignore index c766352..8998d08 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,7 @@ build rootfs/boot/kernel +rootfs/bin +rootfs/initrd.tar .vscode *.log +initrd diff --git a/.gitignore b/.gitignore index c766352..8998d08 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,7 @@ build rootfs/boot/kernel +rootfs/bin +rootfs/initrd.tar .vscode *.log +initrd diff --git a/Makefile b/Makefile index 4614e12..801e89e 100644 --- a/Makefile +++ b/Makefile @@ -6,8 +6,6 @@ LD_FLAGS = -z max-page-size=0x1000 -T link.ld AS = nasm ASFlAGS = -felf32 -GENISO = genisoimage -GENISOFLAGS = -R -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4 -input-charset utf8 -quiet -boot-info-table -A tree-os EMU = qemu-system-x86_64 EMUFLAGS = -m 1G -drive format=raw,file=$(IMAGE_FILE) -no-reboot -no-shutdown -monitor stdio @@ -16,13 +14,13 @@ SOURCE_FILES := $(shell find src/kernel -name *.c -or -name *.asm -or -name *.s) OBJS := $(SOURCE_FILES:%=$(BUILD_FOLDER)/%.o) USER_PROGRAMS := $(shell ls src/userland) -USER_PROGRAM_NAMES := $(USER_PROGRAMS:%=rootfs/%) +USER_PROGRAM_NAMES := $(USER_PROGRAMS:%=initrd/%) run: $(IMAGE_FILE) @echo "starting qemu" @$(EMU) $(EMUFLAGS) -$(IMAGE_FILE): rootfs/boot/kernel $(USER_PROGRAM_NAMES) +$(IMAGE_FILE): rootfs/boot/kernel rootfs/initrd.tar echo "creating the iso image" dd if=/dev/zero of=$(IMAGE_FILE) bs=512 count=32768 &&\ printf "n\np\n1\n\n\na\nw\n" | fdisk $(IMAGE_FILE) &&\ @@ -34,13 +32,15 @@ sudo mount $$loop1 /mnt &&\ sudo grub-install --root-directory=/mnt --no-floppy --modules="normal part_msdos multiboot" $$loop0 &&\ sudo cp -RT rootfs/ /mnt &&\ - sudo rm -r /mnt/boot/grub/fonts &&\ sync &&\ sudo umount /mnt &&\ sudo losetup -d $$loop0 &&\ sudo losetup -d $$loop1 -rootfs/boot/kernel: $(OBJS) +rootfs/initrd.tar: $(USER_PROGRAM_NAMES) + tar cvf rootfs/initrd.tar initrd/ + +rootfs/boot/kernel: $(OBJS) link.ld @echo "linking" @$(LD) $(LD_FLAGS) -o $@ $(OBJS) @@ -59,14 +59,10 @@ @mkdir -p $(dir $@) @$(CC) $(CCFLAGS) -r $< -o $@ -rootfs/%: src/userland/% iso/modules +initrd/%: src/userland/% @echo "compiling userspace program $<" @make -C $< clean: @echo "clearing build folder" - @rm -r $(BUILD_FOLDER) tree-os.iso - -cleanELF: - @echo "clearing the elf file" - @rm iso/boot/tree-os.elf + @rm -r $(BUILD_FOLDER) diff --git a/.gitignore b/.gitignore index c766352..8998d08 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,7 @@ build rootfs/boot/kernel +rootfs/bin +rootfs/initrd.tar .vscode *.log +initrd diff --git a/Makefile b/Makefile index 4614e12..801e89e 100644 --- a/Makefile +++ b/Makefile @@ -6,8 +6,6 @@ LD_FLAGS = -z max-page-size=0x1000 -T link.ld AS = nasm ASFlAGS = -felf32 -GENISO = genisoimage -GENISOFLAGS = -R -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4 -input-charset utf8 -quiet -boot-info-table -A tree-os EMU = qemu-system-x86_64 EMUFLAGS = -m 1G -drive format=raw,file=$(IMAGE_FILE) -no-reboot -no-shutdown -monitor stdio @@ -16,13 +14,13 @@ SOURCE_FILES := $(shell find src/kernel -name *.c -or -name *.asm -or -name *.s) OBJS := $(SOURCE_FILES:%=$(BUILD_FOLDER)/%.o) USER_PROGRAMS := $(shell ls src/userland) -USER_PROGRAM_NAMES := $(USER_PROGRAMS:%=rootfs/%) +USER_PROGRAM_NAMES := $(USER_PROGRAMS:%=initrd/%) run: $(IMAGE_FILE) @echo "starting qemu" @$(EMU) $(EMUFLAGS) -$(IMAGE_FILE): rootfs/boot/kernel $(USER_PROGRAM_NAMES) +$(IMAGE_FILE): rootfs/boot/kernel rootfs/initrd.tar echo "creating the iso image" dd if=/dev/zero of=$(IMAGE_FILE) bs=512 count=32768 &&\ printf "n\np\n1\n\n\na\nw\n" | fdisk $(IMAGE_FILE) &&\ @@ -34,13 +32,15 @@ sudo mount $$loop1 /mnt &&\ sudo grub-install --root-directory=/mnt --no-floppy --modules="normal part_msdos multiboot" $$loop0 &&\ sudo cp -RT rootfs/ /mnt &&\ - sudo rm -r /mnt/boot/grub/fonts &&\ sync &&\ sudo umount /mnt &&\ sudo losetup -d $$loop0 &&\ sudo losetup -d $$loop1 -rootfs/boot/kernel: $(OBJS) +rootfs/initrd.tar: $(USER_PROGRAM_NAMES) + tar cvf rootfs/initrd.tar initrd/ + +rootfs/boot/kernel: $(OBJS) link.ld @echo "linking" @$(LD) $(LD_FLAGS) -o $@ $(OBJS) @@ -59,14 +59,10 @@ @mkdir -p $(dir $@) @$(CC) $(CCFLAGS) -r $< -o $@ -rootfs/%: src/userland/% iso/modules +initrd/%: src/userland/% @echo "compiling userspace program $<" @make -C $< clean: @echo "clearing build folder" - @rm -r $(BUILD_FOLDER) tree-os.iso - -cleanELF: - @echo "clearing the elf file" - @rm iso/boot/tree-os.elf + @rm -r $(BUILD_FOLDER) diff --git a/link.ld b/link.ld index 05b49c4..6f0a9ee 100644 --- a/link.ld +++ b/link.ld @@ -7,7 +7,6 @@ .boot : { *(.boot) } - bootEnd = .; . += 0xFFB00000; .text : AT(ADDR(.text) - 0xFFB00000) { @@ -24,5 +23,11 @@ .bss :AT(ADDR(.bss) - 0xFFB00000) { *(.bss) + . = ALIGN(4M); + } + + . = 0x500000; + .kernelReserve :AT(0x500000) { + . += 0x400000; } } diff --git a/.gitignore b/.gitignore index c766352..8998d08 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,7 @@ build rootfs/boot/kernel +rootfs/bin +rootfs/initrd.tar .vscode *.log +initrd diff --git a/Makefile b/Makefile index 4614e12..801e89e 100644 --- a/Makefile +++ b/Makefile @@ -6,8 +6,6 @@ LD_FLAGS = -z max-page-size=0x1000 -T link.ld AS = nasm ASFlAGS = -felf32 -GENISO = genisoimage -GENISOFLAGS = -R -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4 -input-charset utf8 -quiet -boot-info-table -A tree-os EMU = qemu-system-x86_64 EMUFLAGS = -m 1G -drive format=raw,file=$(IMAGE_FILE) -no-reboot -no-shutdown -monitor stdio @@ -16,13 +14,13 @@ SOURCE_FILES := $(shell find src/kernel -name *.c -or -name *.asm -or -name *.s) OBJS := $(SOURCE_FILES:%=$(BUILD_FOLDER)/%.o) USER_PROGRAMS := $(shell ls src/userland) -USER_PROGRAM_NAMES := $(USER_PROGRAMS:%=rootfs/%) +USER_PROGRAM_NAMES := $(USER_PROGRAMS:%=initrd/%) run: $(IMAGE_FILE) @echo "starting qemu" @$(EMU) $(EMUFLAGS) -$(IMAGE_FILE): rootfs/boot/kernel $(USER_PROGRAM_NAMES) +$(IMAGE_FILE): rootfs/boot/kernel rootfs/initrd.tar echo "creating the iso image" dd if=/dev/zero of=$(IMAGE_FILE) bs=512 count=32768 &&\ printf "n\np\n1\n\n\na\nw\n" | fdisk $(IMAGE_FILE) &&\ @@ -34,13 +32,15 @@ sudo mount $$loop1 /mnt &&\ sudo grub-install --root-directory=/mnt --no-floppy --modules="normal part_msdos multiboot" $$loop0 &&\ sudo cp -RT rootfs/ /mnt &&\ - sudo rm -r /mnt/boot/grub/fonts &&\ sync &&\ sudo umount /mnt &&\ sudo losetup -d $$loop0 &&\ sudo losetup -d $$loop1 -rootfs/boot/kernel: $(OBJS) +rootfs/initrd.tar: $(USER_PROGRAM_NAMES) + tar cvf rootfs/initrd.tar initrd/ + +rootfs/boot/kernel: $(OBJS) link.ld @echo "linking" @$(LD) $(LD_FLAGS) -o $@ $(OBJS) @@ -59,14 +59,10 @@ @mkdir -p $(dir $@) @$(CC) $(CCFLAGS) -r $< -o $@ -rootfs/%: src/userland/% iso/modules +initrd/%: src/userland/% @echo "compiling userspace program $<" @make -C $< clean: @echo "clearing build folder" - @rm -r $(BUILD_FOLDER) tree-os.iso - -cleanELF: - @echo "clearing the elf file" - @rm iso/boot/tree-os.elf + @rm -r $(BUILD_FOLDER) diff --git a/link.ld b/link.ld index 05b49c4..6f0a9ee 100644 --- a/link.ld +++ b/link.ld @@ -7,7 +7,6 @@ .boot : { *(.boot) } - bootEnd = .; . += 0xFFB00000; .text : AT(ADDR(.text) - 0xFFB00000) { @@ -24,5 +23,11 @@ .bss :AT(ADDR(.bss) - 0xFFB00000) { *(.bss) + . = ALIGN(4M); + } + + . = 0x500000; + .kernelReserve :AT(0x500000) { + . += 0x400000; } } diff --git a/rootfs/boot/grub/grub.cfg b/rootfs/boot/grub/grub.cfg index c3394c2..2470bcc 100644 --- a/rootfs/boot/grub/grub.cfg +++ b/rootfs/boot/grub/grub.cfg @@ -3,5 +3,6 @@ menuentry "honey os" { multiboot2 /boot/kernel + module2 /initrd.tar boot } diff --git a/.gitignore b/.gitignore index c766352..8998d08 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,7 @@ build rootfs/boot/kernel +rootfs/bin +rootfs/initrd.tar .vscode *.log +initrd diff --git a/Makefile b/Makefile index 4614e12..801e89e 100644 --- a/Makefile +++ b/Makefile @@ -6,8 +6,6 @@ LD_FLAGS = -z max-page-size=0x1000 -T link.ld AS = nasm ASFlAGS = -felf32 -GENISO = genisoimage -GENISOFLAGS = -R -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4 -input-charset utf8 -quiet -boot-info-table -A tree-os EMU = qemu-system-x86_64 EMUFLAGS = -m 1G -drive format=raw,file=$(IMAGE_FILE) -no-reboot -no-shutdown -monitor stdio @@ -16,13 +14,13 @@ SOURCE_FILES := $(shell find src/kernel -name *.c -or -name *.asm -or -name *.s) OBJS := $(SOURCE_FILES:%=$(BUILD_FOLDER)/%.o) USER_PROGRAMS := $(shell ls src/userland) -USER_PROGRAM_NAMES := $(USER_PROGRAMS:%=rootfs/%) +USER_PROGRAM_NAMES := $(USER_PROGRAMS:%=initrd/%) run: $(IMAGE_FILE) @echo "starting qemu" @$(EMU) $(EMUFLAGS) -$(IMAGE_FILE): rootfs/boot/kernel $(USER_PROGRAM_NAMES) +$(IMAGE_FILE): rootfs/boot/kernel rootfs/initrd.tar echo "creating the iso image" dd if=/dev/zero of=$(IMAGE_FILE) bs=512 count=32768 &&\ printf "n\np\n1\n\n\na\nw\n" | fdisk $(IMAGE_FILE) &&\ @@ -34,13 +32,15 @@ sudo mount $$loop1 /mnt &&\ sudo grub-install --root-directory=/mnt --no-floppy --modules="normal part_msdos multiboot" $$loop0 &&\ sudo cp -RT rootfs/ /mnt &&\ - sudo rm -r /mnt/boot/grub/fonts &&\ sync &&\ sudo umount /mnt &&\ sudo losetup -d $$loop0 &&\ sudo losetup -d $$loop1 -rootfs/boot/kernel: $(OBJS) +rootfs/initrd.tar: $(USER_PROGRAM_NAMES) + tar cvf rootfs/initrd.tar initrd/ + +rootfs/boot/kernel: $(OBJS) link.ld @echo "linking" @$(LD) $(LD_FLAGS) -o $@ $(OBJS) @@ -59,14 +59,10 @@ @mkdir -p $(dir $@) @$(CC) $(CCFLAGS) -r $< -o $@ -rootfs/%: src/userland/% iso/modules +initrd/%: src/userland/% @echo "compiling userspace program $<" @make -C $< clean: @echo "clearing build folder" - @rm -r $(BUILD_FOLDER) tree-os.iso - -cleanELF: - @echo "clearing the elf file" - @rm iso/boot/tree-os.elf + @rm -r $(BUILD_FOLDER) diff --git a/link.ld b/link.ld index 05b49c4..6f0a9ee 100644 --- a/link.ld +++ b/link.ld @@ -7,7 +7,6 @@ .boot : { *(.boot) } - bootEnd = .; . += 0xFFB00000; .text : AT(ADDR(.text) - 0xFFB00000) { @@ -24,5 +23,11 @@ .bss :AT(ADDR(.bss) - 0xFFB00000) { *(.bss) + . = ALIGN(4M); + } + + . = 0x500000; + .kernelReserve :AT(0x500000) { + . += 0x400000; } } diff --git a/rootfs/boot/grub/grub.cfg b/rootfs/boot/grub/grub.cfg index c3394c2..2470bcc 100644 --- a/rootfs/boot/grub/grub.cfg +++ b/rootfs/boot/grub/grub.cfg @@ -3,5 +3,6 @@ menuentry "honey os" { multiboot2 /boot/kernel + module2 /initrd.tar boot } diff --git a/src/kernel/boot/boot.asm b/src/kernel/boot/boot.asm index 2288daa..dc00a9d 100644 --- a/src/kernel/boot/boot.asm +++ b/src/kernel/boot/boot.asm @@ -14,7 +14,6 @@ .end: extern kernelMain -extern multibootInfo %define pageDirectory 0x500000 %define kernelPageTable 0x501000 @@ -24,8 +23,11 @@ %define mappedStackEnd 0xFFBFFFFF %define originalPageTable 0x503000 +ebxStart: db 0x00000000 + global _start _start: + mov [ebxStart], ebx mov esp, stackEnd lgdt [gdt32.end] mov ax, 16 @@ -35,7 +37,7 @@ mov fs, ax mov gs, ax jmp 0x08:.setupPaging -.setupPaging +.setupPaging: mov eax, pageDirectory mov ebx, originalPageTable mov ecx, 0 @@ -114,8 +116,10 @@ section .text higherKernelEntry: -.cleanOriginalEntryCode + mov ebx, [ebxStart] + push ebx +.cleanOriginalEntryCode: mov eax, 0xFF800000 mov dword [eax], 0 call kernelMain - jmp $ \ No newline at end of file + jmp $ diff --git a/.gitignore b/.gitignore index c766352..8998d08 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,7 @@ build rootfs/boot/kernel +rootfs/bin +rootfs/initrd.tar .vscode *.log +initrd diff --git a/Makefile b/Makefile index 4614e12..801e89e 100644 --- a/Makefile +++ b/Makefile @@ -6,8 +6,6 @@ LD_FLAGS = -z max-page-size=0x1000 -T link.ld AS = nasm ASFlAGS = -felf32 -GENISO = genisoimage -GENISOFLAGS = -R -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4 -input-charset utf8 -quiet -boot-info-table -A tree-os EMU = qemu-system-x86_64 EMUFLAGS = -m 1G -drive format=raw,file=$(IMAGE_FILE) -no-reboot -no-shutdown -monitor stdio @@ -16,13 +14,13 @@ SOURCE_FILES := $(shell find src/kernel -name *.c -or -name *.asm -or -name *.s) OBJS := $(SOURCE_FILES:%=$(BUILD_FOLDER)/%.o) USER_PROGRAMS := $(shell ls src/userland) -USER_PROGRAM_NAMES := $(USER_PROGRAMS:%=rootfs/%) +USER_PROGRAM_NAMES := $(USER_PROGRAMS:%=initrd/%) run: $(IMAGE_FILE) @echo "starting qemu" @$(EMU) $(EMUFLAGS) -$(IMAGE_FILE): rootfs/boot/kernel $(USER_PROGRAM_NAMES) +$(IMAGE_FILE): rootfs/boot/kernel rootfs/initrd.tar echo "creating the iso image" dd if=/dev/zero of=$(IMAGE_FILE) bs=512 count=32768 &&\ printf "n\np\n1\n\n\na\nw\n" | fdisk $(IMAGE_FILE) &&\ @@ -34,13 +32,15 @@ sudo mount $$loop1 /mnt &&\ sudo grub-install --root-directory=/mnt --no-floppy --modules="normal part_msdos multiboot" $$loop0 &&\ sudo cp -RT rootfs/ /mnt &&\ - sudo rm -r /mnt/boot/grub/fonts &&\ sync &&\ sudo umount /mnt &&\ sudo losetup -d $$loop0 &&\ sudo losetup -d $$loop1 -rootfs/boot/kernel: $(OBJS) +rootfs/initrd.tar: $(USER_PROGRAM_NAMES) + tar cvf rootfs/initrd.tar initrd/ + +rootfs/boot/kernel: $(OBJS) link.ld @echo "linking" @$(LD) $(LD_FLAGS) -o $@ $(OBJS) @@ -59,14 +59,10 @@ @mkdir -p $(dir $@) @$(CC) $(CCFLAGS) -r $< -o $@ -rootfs/%: src/userland/% iso/modules +initrd/%: src/userland/% @echo "compiling userspace program $<" @make -C $< clean: @echo "clearing build folder" - @rm -r $(BUILD_FOLDER) tree-os.iso - -cleanELF: - @echo "clearing the elf file" - @rm iso/boot/tree-os.elf + @rm -r $(BUILD_FOLDER) diff --git a/link.ld b/link.ld index 05b49c4..6f0a9ee 100644 --- a/link.ld +++ b/link.ld @@ -7,7 +7,6 @@ .boot : { *(.boot) } - bootEnd = .; . += 0xFFB00000; .text : AT(ADDR(.text) - 0xFFB00000) { @@ -24,5 +23,11 @@ .bss :AT(ADDR(.bss) - 0xFFB00000) { *(.bss) + . = ALIGN(4M); + } + + . = 0x500000; + .kernelReserve :AT(0x500000) { + . += 0x400000; } } diff --git a/rootfs/boot/grub/grub.cfg b/rootfs/boot/grub/grub.cfg index c3394c2..2470bcc 100644 --- a/rootfs/boot/grub/grub.cfg +++ b/rootfs/boot/grub/grub.cfg @@ -3,5 +3,6 @@ menuentry "honey os" { multiboot2 /boot/kernel + module2 /initrd.tar boot } diff --git a/src/kernel/boot/boot.asm b/src/kernel/boot/boot.asm index 2288daa..dc00a9d 100644 --- a/src/kernel/boot/boot.asm +++ b/src/kernel/boot/boot.asm @@ -14,7 +14,6 @@ .end: extern kernelMain -extern multibootInfo %define pageDirectory 0x500000 %define kernelPageTable 0x501000 @@ -24,8 +23,11 @@ %define mappedStackEnd 0xFFBFFFFF %define originalPageTable 0x503000 +ebxStart: db 0x00000000 + global _start _start: + mov [ebxStart], ebx mov esp, stackEnd lgdt [gdt32.end] mov ax, 16 @@ -35,7 +37,7 @@ mov fs, ax mov gs, ax jmp 0x08:.setupPaging -.setupPaging +.setupPaging: mov eax, pageDirectory mov ebx, originalPageTable mov ecx, 0 @@ -114,8 +116,10 @@ section .text higherKernelEntry: -.cleanOriginalEntryCode + mov ebx, [ebxStart] + push ebx +.cleanOriginalEntryCode: mov eax, 0xFF800000 mov dword [eax], 0 call kernelMain - jmp $ \ No newline at end of file + jmp $ diff --git a/src/kernel/include/memory.h b/src/kernel/include/memory.h index c5c47c0..1d40818 100644 --- a/src/kernel/include/memory.h +++ b/src/kernel/include/memory.h @@ -4,7 +4,8 @@ #include extern void setupMemory(); -extern void reservePagesUntil(uint32_t endPageId); -extern void memset(uint8_t *target, uint8_t byte, uint32_t size); +extern void reservePagesUntilPhysical(uint32_t endPageId); +extern void memset(void *target, uint8_t byte, uint32_t size); +extern void *kernelMapPhysical(void *address); #endif diff --git a/.gitignore b/.gitignore index c766352..8998d08 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,7 @@ build rootfs/boot/kernel +rootfs/bin +rootfs/initrd.tar .vscode *.log +initrd diff --git a/Makefile b/Makefile index 4614e12..801e89e 100644 --- a/Makefile +++ b/Makefile @@ -6,8 +6,6 @@ LD_FLAGS = -z max-page-size=0x1000 -T link.ld AS = nasm ASFlAGS = -felf32 -GENISO = genisoimage -GENISOFLAGS = -R -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4 -input-charset utf8 -quiet -boot-info-table -A tree-os EMU = qemu-system-x86_64 EMUFLAGS = -m 1G -drive format=raw,file=$(IMAGE_FILE) -no-reboot -no-shutdown -monitor stdio @@ -16,13 +14,13 @@ SOURCE_FILES := $(shell find src/kernel -name *.c -or -name *.asm -or -name *.s) OBJS := $(SOURCE_FILES:%=$(BUILD_FOLDER)/%.o) USER_PROGRAMS := $(shell ls src/userland) -USER_PROGRAM_NAMES := $(USER_PROGRAMS:%=rootfs/%) +USER_PROGRAM_NAMES := $(USER_PROGRAMS:%=initrd/%) run: $(IMAGE_FILE) @echo "starting qemu" @$(EMU) $(EMUFLAGS) -$(IMAGE_FILE): rootfs/boot/kernel $(USER_PROGRAM_NAMES) +$(IMAGE_FILE): rootfs/boot/kernel rootfs/initrd.tar echo "creating the iso image" dd if=/dev/zero of=$(IMAGE_FILE) bs=512 count=32768 &&\ printf "n\np\n1\n\n\na\nw\n" | fdisk $(IMAGE_FILE) &&\ @@ -34,13 +32,15 @@ sudo mount $$loop1 /mnt &&\ sudo grub-install --root-directory=/mnt --no-floppy --modules="normal part_msdos multiboot" $$loop0 &&\ sudo cp -RT rootfs/ /mnt &&\ - sudo rm -r /mnt/boot/grub/fonts &&\ sync &&\ sudo umount /mnt &&\ sudo losetup -d $$loop0 &&\ sudo losetup -d $$loop1 -rootfs/boot/kernel: $(OBJS) +rootfs/initrd.tar: $(USER_PROGRAM_NAMES) + tar cvf rootfs/initrd.tar initrd/ + +rootfs/boot/kernel: $(OBJS) link.ld @echo "linking" @$(LD) $(LD_FLAGS) -o $@ $(OBJS) @@ -59,14 +59,10 @@ @mkdir -p $(dir $@) @$(CC) $(CCFLAGS) -r $< -o $@ -rootfs/%: src/userland/% iso/modules +initrd/%: src/userland/% @echo "compiling userspace program $<" @make -C $< clean: @echo "clearing build folder" - @rm -r $(BUILD_FOLDER) tree-os.iso - -cleanELF: - @echo "clearing the elf file" - @rm iso/boot/tree-os.elf + @rm -r $(BUILD_FOLDER) diff --git a/link.ld b/link.ld index 05b49c4..6f0a9ee 100644 --- a/link.ld +++ b/link.ld @@ -7,7 +7,6 @@ .boot : { *(.boot) } - bootEnd = .; . += 0xFFB00000; .text : AT(ADDR(.text) - 0xFFB00000) { @@ -24,5 +23,11 @@ .bss :AT(ADDR(.bss) - 0xFFB00000) { *(.bss) + . = ALIGN(4M); + } + + . = 0x500000; + .kernelReserve :AT(0x500000) { + . += 0x400000; } } diff --git a/rootfs/boot/grub/grub.cfg b/rootfs/boot/grub/grub.cfg index c3394c2..2470bcc 100644 --- a/rootfs/boot/grub/grub.cfg +++ b/rootfs/boot/grub/grub.cfg @@ -3,5 +3,6 @@ menuentry "honey os" { multiboot2 /boot/kernel + module2 /initrd.tar boot } diff --git a/src/kernel/boot/boot.asm b/src/kernel/boot/boot.asm index 2288daa..dc00a9d 100644 --- a/src/kernel/boot/boot.asm +++ b/src/kernel/boot/boot.asm @@ -14,7 +14,6 @@ .end: extern kernelMain -extern multibootInfo %define pageDirectory 0x500000 %define kernelPageTable 0x501000 @@ -24,8 +23,11 @@ %define mappedStackEnd 0xFFBFFFFF %define originalPageTable 0x503000 +ebxStart: db 0x00000000 + global _start _start: + mov [ebxStart], ebx mov esp, stackEnd lgdt [gdt32.end] mov ax, 16 @@ -35,7 +37,7 @@ mov fs, ax mov gs, ax jmp 0x08:.setupPaging -.setupPaging +.setupPaging: mov eax, pageDirectory mov ebx, originalPageTable mov ecx, 0 @@ -114,8 +116,10 @@ section .text higherKernelEntry: -.cleanOriginalEntryCode + mov ebx, [ebxStart] + push ebx +.cleanOriginalEntryCode: mov eax, 0xFF800000 mov dword [eax], 0 call kernelMain - jmp $ \ No newline at end of file + jmp $ diff --git a/src/kernel/include/memory.h b/src/kernel/include/memory.h index c5c47c0..1d40818 100644 --- a/src/kernel/include/memory.h +++ b/src/kernel/include/memory.h @@ -4,7 +4,8 @@ #include extern void setupMemory(); -extern void reservePagesUntil(uint32_t endPageId); -extern void memset(uint8_t *target, uint8_t byte, uint32_t size); +extern void reservePagesUntilPhysical(uint32_t endPageId); +extern void memset(void *target, uint8_t byte, uint32_t size); +extern void *kernelMapPhysical(void *address); #endif diff --git a/src/kernel/include/multiboot.h b/src/kernel/include/multiboot.h new file mode 100644 index 0000000..26c0f93 --- /dev/null +++ b/src/kernel/include/multiboot.h @@ -0,0 +1,48 @@ +#ifndef MULTIBOOT_H +#define MULTIBOOT_H + +#include + +// note: this structure supports more stuff, but I'm looking for the modules +// here. Look at +// https://android.googlesource.com/platform/external/grub/+/1650e5296608be8925d9831310c9ad3595fd6869/docs/multiboot.info +// for more info + +typedef enum { + BootCommandLineType = 1, + ModulesType = 3, + BasicMemoryInformationType = 4, + BiosBootDeviceType = 5, +} MultibootType; + +typedef struct { + uint32_t type; // multiboot type + uint32_t size; +} MultibootModuleInfo; + +typedef struct { + MultibootModuleInfo; + uint32_t memUpper; + uint32_t memLower; +} BasicMemoryInformation; + +typedef struct { + MultibootModuleInfo; + uint32_t biosDevice; + uint32_t partition; + uint32_t subPartition; +} BiosBootDevice; + +typedef struct { + MultibootModuleInfo; + char string[0]; +} BootCommandLine; + +typedef struct { + MultibootModuleInfo; + uint32_t moduleStart; + uint32_t moduleEnd; + char string[0]; +} Modules; + +#endif diff --git a/.gitignore b/.gitignore index c766352..8998d08 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,7 @@ build rootfs/boot/kernel +rootfs/bin +rootfs/initrd.tar .vscode *.log +initrd diff --git a/Makefile b/Makefile index 4614e12..801e89e 100644 --- a/Makefile +++ b/Makefile @@ -6,8 +6,6 @@ LD_FLAGS = -z max-page-size=0x1000 -T link.ld AS = nasm ASFlAGS = -felf32 -GENISO = genisoimage -GENISOFLAGS = -R -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4 -input-charset utf8 -quiet -boot-info-table -A tree-os EMU = qemu-system-x86_64 EMUFLAGS = -m 1G -drive format=raw,file=$(IMAGE_FILE) -no-reboot -no-shutdown -monitor stdio @@ -16,13 +14,13 @@ SOURCE_FILES := $(shell find src/kernel -name *.c -or -name *.asm -or -name *.s) OBJS := $(SOURCE_FILES:%=$(BUILD_FOLDER)/%.o) USER_PROGRAMS := $(shell ls src/userland) -USER_PROGRAM_NAMES := $(USER_PROGRAMS:%=rootfs/%) +USER_PROGRAM_NAMES := $(USER_PROGRAMS:%=initrd/%) run: $(IMAGE_FILE) @echo "starting qemu" @$(EMU) $(EMUFLAGS) -$(IMAGE_FILE): rootfs/boot/kernel $(USER_PROGRAM_NAMES) +$(IMAGE_FILE): rootfs/boot/kernel rootfs/initrd.tar echo "creating the iso image" dd if=/dev/zero of=$(IMAGE_FILE) bs=512 count=32768 &&\ printf "n\np\n1\n\n\na\nw\n" | fdisk $(IMAGE_FILE) &&\ @@ -34,13 +32,15 @@ sudo mount $$loop1 /mnt &&\ sudo grub-install --root-directory=/mnt --no-floppy --modules="normal part_msdos multiboot" $$loop0 &&\ sudo cp -RT rootfs/ /mnt &&\ - sudo rm -r /mnt/boot/grub/fonts &&\ sync &&\ sudo umount /mnt &&\ sudo losetup -d $$loop0 &&\ sudo losetup -d $$loop1 -rootfs/boot/kernel: $(OBJS) +rootfs/initrd.tar: $(USER_PROGRAM_NAMES) + tar cvf rootfs/initrd.tar initrd/ + +rootfs/boot/kernel: $(OBJS) link.ld @echo "linking" @$(LD) $(LD_FLAGS) -o $@ $(OBJS) @@ -59,14 +59,10 @@ @mkdir -p $(dir $@) @$(CC) $(CCFLAGS) -r $< -o $@ -rootfs/%: src/userland/% iso/modules +initrd/%: src/userland/% @echo "compiling userspace program $<" @make -C $< clean: @echo "clearing build folder" - @rm -r $(BUILD_FOLDER) tree-os.iso - -cleanELF: - @echo "clearing the elf file" - @rm iso/boot/tree-os.elf + @rm -r $(BUILD_FOLDER) diff --git a/link.ld b/link.ld index 05b49c4..6f0a9ee 100644 --- a/link.ld +++ b/link.ld @@ -7,7 +7,6 @@ .boot : { *(.boot) } - bootEnd = .; . += 0xFFB00000; .text : AT(ADDR(.text) - 0xFFB00000) { @@ -24,5 +23,11 @@ .bss :AT(ADDR(.bss) - 0xFFB00000) { *(.bss) + . = ALIGN(4M); + } + + . = 0x500000; + .kernelReserve :AT(0x500000) { + . += 0x400000; } } diff --git a/rootfs/boot/grub/grub.cfg b/rootfs/boot/grub/grub.cfg index c3394c2..2470bcc 100644 --- a/rootfs/boot/grub/grub.cfg +++ b/rootfs/boot/grub/grub.cfg @@ -3,5 +3,6 @@ menuentry "honey os" { multiboot2 /boot/kernel + module2 /initrd.tar boot } diff --git a/src/kernel/boot/boot.asm b/src/kernel/boot/boot.asm index 2288daa..dc00a9d 100644 --- a/src/kernel/boot/boot.asm +++ b/src/kernel/boot/boot.asm @@ -14,7 +14,6 @@ .end: extern kernelMain -extern multibootInfo %define pageDirectory 0x500000 %define kernelPageTable 0x501000 @@ -24,8 +23,11 @@ %define mappedStackEnd 0xFFBFFFFF %define originalPageTable 0x503000 +ebxStart: db 0x00000000 + global _start _start: + mov [ebxStart], ebx mov esp, stackEnd lgdt [gdt32.end] mov ax, 16 @@ -35,7 +37,7 @@ mov fs, ax mov gs, ax jmp 0x08:.setupPaging -.setupPaging +.setupPaging: mov eax, pageDirectory mov ebx, originalPageTable mov ecx, 0 @@ -114,8 +116,10 @@ section .text higherKernelEntry: -.cleanOriginalEntryCode + mov ebx, [ebxStart] + push ebx +.cleanOriginalEntryCode: mov eax, 0xFF800000 mov dword [eax], 0 call kernelMain - jmp $ \ No newline at end of file + jmp $ diff --git a/src/kernel/include/memory.h b/src/kernel/include/memory.h index c5c47c0..1d40818 100644 --- a/src/kernel/include/memory.h +++ b/src/kernel/include/memory.h @@ -4,7 +4,8 @@ #include extern void setupMemory(); -extern void reservePagesUntil(uint32_t endPageId); -extern void memset(uint8_t *target, uint8_t byte, uint32_t size); +extern void reservePagesUntilPhysical(uint32_t endPageId); +extern void memset(void *target, uint8_t byte, uint32_t size); +extern void *kernelMapPhysical(void *address); #endif diff --git a/src/kernel/include/multiboot.h b/src/kernel/include/multiboot.h new file mode 100644 index 0000000..26c0f93 --- /dev/null +++ b/src/kernel/include/multiboot.h @@ -0,0 +1,48 @@ +#ifndef MULTIBOOT_H +#define MULTIBOOT_H + +#include + +// note: this structure supports more stuff, but I'm looking for the modules +// here. Look at +// https://android.googlesource.com/platform/external/grub/+/1650e5296608be8925d9831310c9ad3595fd6869/docs/multiboot.info +// for more info + +typedef enum { + BootCommandLineType = 1, + ModulesType = 3, + BasicMemoryInformationType = 4, + BiosBootDeviceType = 5, +} MultibootType; + +typedef struct { + uint32_t type; // multiboot type + uint32_t size; +} MultibootModuleInfo; + +typedef struct { + MultibootModuleInfo; + uint32_t memUpper; + uint32_t memLower; +} BasicMemoryInformation; + +typedef struct { + MultibootModuleInfo; + uint32_t biosDevice; + uint32_t partition; + uint32_t subPartition; +} BiosBootDevice; + +typedef struct { + MultibootModuleInfo; + char string[0]; +} BootCommandLine; + +typedef struct { + MultibootModuleInfo; + uint32_t moduleStart; + uint32_t moduleEnd; + char string[0]; +} Modules; + +#endif diff --git a/src/kernel/include/util.h b/src/kernel/include/util.h new file mode 100644 index 0000000..672e7dd --- /dev/null +++ b/src/kernel/include/util.h @@ -0,0 +1,7 @@ +#ifndef UTIL_H +#define UTIL_H + +#define U32(x) (uint32_t)(uintptr_t)(x) +#define PTR(x) (void *)(uintptr_t)(x) + +#endif diff --git a/.gitignore b/.gitignore index c766352..8998d08 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,7 @@ build rootfs/boot/kernel +rootfs/bin +rootfs/initrd.tar .vscode *.log +initrd diff --git a/Makefile b/Makefile index 4614e12..801e89e 100644 --- a/Makefile +++ b/Makefile @@ -6,8 +6,6 @@ LD_FLAGS = -z max-page-size=0x1000 -T link.ld AS = nasm ASFlAGS = -felf32 -GENISO = genisoimage -GENISOFLAGS = -R -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4 -input-charset utf8 -quiet -boot-info-table -A tree-os EMU = qemu-system-x86_64 EMUFLAGS = -m 1G -drive format=raw,file=$(IMAGE_FILE) -no-reboot -no-shutdown -monitor stdio @@ -16,13 +14,13 @@ SOURCE_FILES := $(shell find src/kernel -name *.c -or -name *.asm -or -name *.s) OBJS := $(SOURCE_FILES:%=$(BUILD_FOLDER)/%.o) USER_PROGRAMS := $(shell ls src/userland) -USER_PROGRAM_NAMES := $(USER_PROGRAMS:%=rootfs/%) +USER_PROGRAM_NAMES := $(USER_PROGRAMS:%=initrd/%) run: $(IMAGE_FILE) @echo "starting qemu" @$(EMU) $(EMUFLAGS) -$(IMAGE_FILE): rootfs/boot/kernel $(USER_PROGRAM_NAMES) +$(IMAGE_FILE): rootfs/boot/kernel rootfs/initrd.tar echo "creating the iso image" dd if=/dev/zero of=$(IMAGE_FILE) bs=512 count=32768 &&\ printf "n\np\n1\n\n\na\nw\n" | fdisk $(IMAGE_FILE) &&\ @@ -34,13 +32,15 @@ sudo mount $$loop1 /mnt &&\ sudo grub-install --root-directory=/mnt --no-floppy --modules="normal part_msdos multiboot" $$loop0 &&\ sudo cp -RT rootfs/ /mnt &&\ - sudo rm -r /mnt/boot/grub/fonts &&\ sync &&\ sudo umount /mnt &&\ sudo losetup -d $$loop0 &&\ sudo losetup -d $$loop1 -rootfs/boot/kernel: $(OBJS) +rootfs/initrd.tar: $(USER_PROGRAM_NAMES) + tar cvf rootfs/initrd.tar initrd/ + +rootfs/boot/kernel: $(OBJS) link.ld @echo "linking" @$(LD) $(LD_FLAGS) -o $@ $(OBJS) @@ -59,14 +59,10 @@ @mkdir -p $(dir $@) @$(CC) $(CCFLAGS) -r $< -o $@ -rootfs/%: src/userland/% iso/modules +initrd/%: src/userland/% @echo "compiling userspace program $<" @make -C $< clean: @echo "clearing build folder" - @rm -r $(BUILD_FOLDER) tree-os.iso - -cleanELF: - @echo "clearing the elf file" - @rm iso/boot/tree-os.elf + @rm -r $(BUILD_FOLDER) diff --git a/link.ld b/link.ld index 05b49c4..6f0a9ee 100644 --- a/link.ld +++ b/link.ld @@ -7,7 +7,6 @@ .boot : { *(.boot) } - bootEnd = .; . += 0xFFB00000; .text : AT(ADDR(.text) - 0xFFB00000) { @@ -24,5 +23,11 @@ .bss :AT(ADDR(.bss) - 0xFFB00000) { *(.bss) + . = ALIGN(4M); + } + + . = 0x500000; + .kernelReserve :AT(0x500000) { + . += 0x400000; } } diff --git a/rootfs/boot/grub/grub.cfg b/rootfs/boot/grub/grub.cfg index c3394c2..2470bcc 100644 --- a/rootfs/boot/grub/grub.cfg +++ b/rootfs/boot/grub/grub.cfg @@ -3,5 +3,6 @@ menuentry "honey os" { multiboot2 /boot/kernel + module2 /initrd.tar boot } diff --git a/src/kernel/boot/boot.asm b/src/kernel/boot/boot.asm index 2288daa..dc00a9d 100644 --- a/src/kernel/boot/boot.asm +++ b/src/kernel/boot/boot.asm @@ -14,7 +14,6 @@ .end: extern kernelMain -extern multibootInfo %define pageDirectory 0x500000 %define kernelPageTable 0x501000 @@ -24,8 +23,11 @@ %define mappedStackEnd 0xFFBFFFFF %define originalPageTable 0x503000 +ebxStart: db 0x00000000 + global _start _start: + mov [ebxStart], ebx mov esp, stackEnd lgdt [gdt32.end] mov ax, 16 @@ -35,7 +37,7 @@ mov fs, ax mov gs, ax jmp 0x08:.setupPaging -.setupPaging +.setupPaging: mov eax, pageDirectory mov ebx, originalPageTable mov ecx, 0 @@ -114,8 +116,10 @@ section .text higherKernelEntry: -.cleanOriginalEntryCode + mov ebx, [ebxStart] + push ebx +.cleanOriginalEntryCode: mov eax, 0xFF800000 mov dword [eax], 0 call kernelMain - jmp $ \ No newline at end of file + jmp $ diff --git a/src/kernel/include/memory.h b/src/kernel/include/memory.h index c5c47c0..1d40818 100644 --- a/src/kernel/include/memory.h +++ b/src/kernel/include/memory.h @@ -4,7 +4,8 @@ #include extern void setupMemory(); -extern void reservePagesUntil(uint32_t endPageId); -extern void memset(uint8_t *target, uint8_t byte, uint32_t size); +extern void reservePagesUntilPhysical(uint32_t endPageId); +extern void memset(void *target, uint8_t byte, uint32_t size); +extern void *kernelMapPhysical(void *address); #endif diff --git a/src/kernel/include/multiboot.h b/src/kernel/include/multiboot.h new file mode 100644 index 0000000..26c0f93 --- /dev/null +++ b/src/kernel/include/multiboot.h @@ -0,0 +1,48 @@ +#ifndef MULTIBOOT_H +#define MULTIBOOT_H + +#include + +// note: this structure supports more stuff, but I'm looking for the modules +// here. Look at +// https://android.googlesource.com/platform/external/grub/+/1650e5296608be8925d9831310c9ad3595fd6869/docs/multiboot.info +// for more info + +typedef enum { + BootCommandLineType = 1, + ModulesType = 3, + BasicMemoryInformationType = 4, + BiosBootDeviceType = 5, +} MultibootType; + +typedef struct { + uint32_t type; // multiboot type + uint32_t size; +} MultibootModuleInfo; + +typedef struct { + MultibootModuleInfo; + uint32_t memUpper; + uint32_t memLower; +} BasicMemoryInformation; + +typedef struct { + MultibootModuleInfo; + uint32_t biosDevice; + uint32_t partition; + uint32_t subPartition; +} BiosBootDevice; + +typedef struct { + MultibootModuleInfo; + char string[0]; +} BootCommandLine; + +typedef struct { + MultibootModuleInfo; + uint32_t moduleStart; + uint32_t moduleEnd; + char string[0]; +} Modules; + +#endif diff --git a/src/kernel/include/util.h b/src/kernel/include/util.h new file mode 100644 index 0000000..672e7dd --- /dev/null +++ b/src/kernel/include/util.h @@ -0,0 +1,7 @@ +#ifndef UTIL_H +#define UTIL_H + +#define U32(x) (uint32_t)(uintptr_t)(x) +#define PTR(x) (void *)(uintptr_t)(x) + +#endif diff --git a/src/kernel/main.c b/src/kernel/main.c index a7c59eb..3d19504 100644 --- a/src/kernel/main.c +++ b/src/kernel/main.c @@ -1,10 +1,11 @@ #include +#include #include -void *multibootInfo; // set by bootloader - -void kernelMain() { +void kernelMain(void *multibootInfo) { setupMemory(); + void *address = kernelMapPhysical(multibootInfo); + asm("mov %%eax, %0" ::"r"(address)); while (1) ; } diff --git a/.gitignore b/.gitignore index c766352..8998d08 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,7 @@ build rootfs/boot/kernel +rootfs/bin +rootfs/initrd.tar .vscode *.log +initrd diff --git a/Makefile b/Makefile index 4614e12..801e89e 100644 --- a/Makefile +++ b/Makefile @@ -6,8 +6,6 @@ LD_FLAGS = -z max-page-size=0x1000 -T link.ld AS = nasm ASFlAGS = -felf32 -GENISO = genisoimage -GENISOFLAGS = -R -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4 -input-charset utf8 -quiet -boot-info-table -A tree-os EMU = qemu-system-x86_64 EMUFLAGS = -m 1G -drive format=raw,file=$(IMAGE_FILE) -no-reboot -no-shutdown -monitor stdio @@ -16,13 +14,13 @@ SOURCE_FILES := $(shell find src/kernel -name *.c -or -name *.asm -or -name *.s) OBJS := $(SOURCE_FILES:%=$(BUILD_FOLDER)/%.o) USER_PROGRAMS := $(shell ls src/userland) -USER_PROGRAM_NAMES := $(USER_PROGRAMS:%=rootfs/%) +USER_PROGRAM_NAMES := $(USER_PROGRAMS:%=initrd/%) run: $(IMAGE_FILE) @echo "starting qemu" @$(EMU) $(EMUFLAGS) -$(IMAGE_FILE): rootfs/boot/kernel $(USER_PROGRAM_NAMES) +$(IMAGE_FILE): rootfs/boot/kernel rootfs/initrd.tar echo "creating the iso image" dd if=/dev/zero of=$(IMAGE_FILE) bs=512 count=32768 &&\ printf "n\np\n1\n\n\na\nw\n" | fdisk $(IMAGE_FILE) &&\ @@ -34,13 +32,15 @@ sudo mount $$loop1 /mnt &&\ sudo grub-install --root-directory=/mnt --no-floppy --modules="normal part_msdos multiboot" $$loop0 &&\ sudo cp -RT rootfs/ /mnt &&\ - sudo rm -r /mnt/boot/grub/fonts &&\ sync &&\ sudo umount /mnt &&\ sudo losetup -d $$loop0 &&\ sudo losetup -d $$loop1 -rootfs/boot/kernel: $(OBJS) +rootfs/initrd.tar: $(USER_PROGRAM_NAMES) + tar cvf rootfs/initrd.tar initrd/ + +rootfs/boot/kernel: $(OBJS) link.ld @echo "linking" @$(LD) $(LD_FLAGS) -o $@ $(OBJS) @@ -59,14 +59,10 @@ @mkdir -p $(dir $@) @$(CC) $(CCFLAGS) -r $< -o $@ -rootfs/%: src/userland/% iso/modules +initrd/%: src/userland/% @echo "compiling userspace program $<" @make -C $< clean: @echo "clearing build folder" - @rm -r $(BUILD_FOLDER) tree-os.iso - -cleanELF: - @echo "clearing the elf file" - @rm iso/boot/tree-os.elf + @rm -r $(BUILD_FOLDER) diff --git a/link.ld b/link.ld index 05b49c4..6f0a9ee 100644 --- a/link.ld +++ b/link.ld @@ -7,7 +7,6 @@ .boot : { *(.boot) } - bootEnd = .; . += 0xFFB00000; .text : AT(ADDR(.text) - 0xFFB00000) { @@ -24,5 +23,11 @@ .bss :AT(ADDR(.bss) - 0xFFB00000) { *(.bss) + . = ALIGN(4M); + } + + . = 0x500000; + .kernelReserve :AT(0x500000) { + . += 0x400000; } } diff --git a/rootfs/boot/grub/grub.cfg b/rootfs/boot/grub/grub.cfg index c3394c2..2470bcc 100644 --- a/rootfs/boot/grub/grub.cfg +++ b/rootfs/boot/grub/grub.cfg @@ -3,5 +3,6 @@ menuentry "honey os" { multiboot2 /boot/kernel + module2 /initrd.tar boot } diff --git a/src/kernel/boot/boot.asm b/src/kernel/boot/boot.asm index 2288daa..dc00a9d 100644 --- a/src/kernel/boot/boot.asm +++ b/src/kernel/boot/boot.asm @@ -14,7 +14,6 @@ .end: extern kernelMain -extern multibootInfo %define pageDirectory 0x500000 %define kernelPageTable 0x501000 @@ -24,8 +23,11 @@ %define mappedStackEnd 0xFFBFFFFF %define originalPageTable 0x503000 +ebxStart: db 0x00000000 + global _start _start: + mov [ebxStart], ebx mov esp, stackEnd lgdt [gdt32.end] mov ax, 16 @@ -35,7 +37,7 @@ mov fs, ax mov gs, ax jmp 0x08:.setupPaging -.setupPaging +.setupPaging: mov eax, pageDirectory mov ebx, originalPageTable mov ecx, 0 @@ -114,8 +116,10 @@ section .text higherKernelEntry: -.cleanOriginalEntryCode + mov ebx, [ebxStart] + push ebx +.cleanOriginalEntryCode: mov eax, 0xFF800000 mov dword [eax], 0 call kernelMain - jmp $ \ No newline at end of file + jmp $ diff --git a/src/kernel/include/memory.h b/src/kernel/include/memory.h index c5c47c0..1d40818 100644 --- a/src/kernel/include/memory.h +++ b/src/kernel/include/memory.h @@ -4,7 +4,8 @@ #include extern void setupMemory(); -extern void reservePagesUntil(uint32_t endPageId); -extern void memset(uint8_t *target, uint8_t byte, uint32_t size); +extern void reservePagesUntilPhysical(uint32_t endPageId); +extern void memset(void *target, uint8_t byte, uint32_t size); +extern void *kernelMapPhysical(void *address); #endif diff --git a/src/kernel/include/multiboot.h b/src/kernel/include/multiboot.h new file mode 100644 index 0000000..26c0f93 --- /dev/null +++ b/src/kernel/include/multiboot.h @@ -0,0 +1,48 @@ +#ifndef MULTIBOOT_H +#define MULTIBOOT_H + +#include + +// note: this structure supports more stuff, but I'm looking for the modules +// here. Look at +// https://android.googlesource.com/platform/external/grub/+/1650e5296608be8925d9831310c9ad3595fd6869/docs/multiboot.info +// for more info + +typedef enum { + BootCommandLineType = 1, + ModulesType = 3, + BasicMemoryInformationType = 4, + BiosBootDeviceType = 5, +} MultibootType; + +typedef struct { + uint32_t type; // multiboot type + uint32_t size; +} MultibootModuleInfo; + +typedef struct { + MultibootModuleInfo; + uint32_t memUpper; + uint32_t memLower; +} BasicMemoryInformation; + +typedef struct { + MultibootModuleInfo; + uint32_t biosDevice; + uint32_t partition; + uint32_t subPartition; +} BiosBootDevice; + +typedef struct { + MultibootModuleInfo; + char string[0]; +} BootCommandLine; + +typedef struct { + MultibootModuleInfo; + uint32_t moduleStart; + uint32_t moduleEnd; + char string[0]; +} Modules; + +#endif diff --git a/src/kernel/include/util.h b/src/kernel/include/util.h new file mode 100644 index 0000000..672e7dd --- /dev/null +++ b/src/kernel/include/util.h @@ -0,0 +1,7 @@ +#ifndef UTIL_H +#define UTIL_H + +#define U32(x) (uint32_t)(uintptr_t)(x) +#define PTR(x) (void *)(uintptr_t)(x) + +#endif diff --git a/src/kernel/main.c b/src/kernel/main.c index a7c59eb..3d19504 100644 --- a/src/kernel/main.c +++ b/src/kernel/main.c @@ -1,10 +1,11 @@ #include +#include #include -void *multibootInfo; // set by bootloader - -void kernelMain() { +void kernelMain(void *multibootInfo) { setupMemory(); + void *address = kernelMapPhysical(multibootInfo); + asm("mov %%eax, %0" ::"r"(address)); while (1) ; } diff --git a/src/kernel/memory/memory.c b/src/kernel/memory/memory.c index 6c4010a..0be4063 100644 --- a/src/kernel/memory/memory.c +++ b/src/kernel/memory/memory.c @@ -2,6 +2,6 @@ #include void setupMemory() { - reservePagesUntil(0x900); // address 0x900000, until the end of where the - // kernel data was mapped + reservePagesUntilPhysical(0x900); // address 0x900000, until the end of + // where the kernel data was mapped } diff --git a/.gitignore b/.gitignore index c766352..8998d08 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,7 @@ build rootfs/boot/kernel +rootfs/bin +rootfs/initrd.tar .vscode *.log +initrd diff --git a/Makefile b/Makefile index 4614e12..801e89e 100644 --- a/Makefile +++ b/Makefile @@ -6,8 +6,6 @@ LD_FLAGS = -z max-page-size=0x1000 -T link.ld AS = nasm ASFlAGS = -felf32 -GENISO = genisoimage -GENISOFLAGS = -R -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4 -input-charset utf8 -quiet -boot-info-table -A tree-os EMU = qemu-system-x86_64 EMUFLAGS = -m 1G -drive format=raw,file=$(IMAGE_FILE) -no-reboot -no-shutdown -monitor stdio @@ -16,13 +14,13 @@ SOURCE_FILES := $(shell find src/kernel -name *.c -or -name *.asm -or -name *.s) OBJS := $(SOURCE_FILES:%=$(BUILD_FOLDER)/%.o) USER_PROGRAMS := $(shell ls src/userland) -USER_PROGRAM_NAMES := $(USER_PROGRAMS:%=rootfs/%) +USER_PROGRAM_NAMES := $(USER_PROGRAMS:%=initrd/%) run: $(IMAGE_FILE) @echo "starting qemu" @$(EMU) $(EMUFLAGS) -$(IMAGE_FILE): rootfs/boot/kernel $(USER_PROGRAM_NAMES) +$(IMAGE_FILE): rootfs/boot/kernel rootfs/initrd.tar echo "creating the iso image" dd if=/dev/zero of=$(IMAGE_FILE) bs=512 count=32768 &&\ printf "n\np\n1\n\n\na\nw\n" | fdisk $(IMAGE_FILE) &&\ @@ -34,13 +32,15 @@ sudo mount $$loop1 /mnt &&\ sudo grub-install --root-directory=/mnt --no-floppy --modules="normal part_msdos multiboot" $$loop0 &&\ sudo cp -RT rootfs/ /mnt &&\ - sudo rm -r /mnt/boot/grub/fonts &&\ sync &&\ sudo umount /mnt &&\ sudo losetup -d $$loop0 &&\ sudo losetup -d $$loop1 -rootfs/boot/kernel: $(OBJS) +rootfs/initrd.tar: $(USER_PROGRAM_NAMES) + tar cvf rootfs/initrd.tar initrd/ + +rootfs/boot/kernel: $(OBJS) link.ld @echo "linking" @$(LD) $(LD_FLAGS) -o $@ $(OBJS) @@ -59,14 +59,10 @@ @mkdir -p $(dir $@) @$(CC) $(CCFLAGS) -r $< -o $@ -rootfs/%: src/userland/% iso/modules +initrd/%: src/userland/% @echo "compiling userspace program $<" @make -C $< clean: @echo "clearing build folder" - @rm -r $(BUILD_FOLDER) tree-os.iso - -cleanELF: - @echo "clearing the elf file" - @rm iso/boot/tree-os.elf + @rm -r $(BUILD_FOLDER) diff --git a/link.ld b/link.ld index 05b49c4..6f0a9ee 100644 --- a/link.ld +++ b/link.ld @@ -7,7 +7,6 @@ .boot : { *(.boot) } - bootEnd = .; . += 0xFFB00000; .text : AT(ADDR(.text) - 0xFFB00000) { @@ -24,5 +23,11 @@ .bss :AT(ADDR(.bss) - 0xFFB00000) { *(.bss) + . = ALIGN(4M); + } + + . = 0x500000; + .kernelReserve :AT(0x500000) { + . += 0x400000; } } diff --git a/rootfs/boot/grub/grub.cfg b/rootfs/boot/grub/grub.cfg index c3394c2..2470bcc 100644 --- a/rootfs/boot/grub/grub.cfg +++ b/rootfs/boot/grub/grub.cfg @@ -3,5 +3,6 @@ menuentry "honey os" { multiboot2 /boot/kernel + module2 /initrd.tar boot } diff --git a/src/kernel/boot/boot.asm b/src/kernel/boot/boot.asm index 2288daa..dc00a9d 100644 --- a/src/kernel/boot/boot.asm +++ b/src/kernel/boot/boot.asm @@ -14,7 +14,6 @@ .end: extern kernelMain -extern multibootInfo %define pageDirectory 0x500000 %define kernelPageTable 0x501000 @@ -24,8 +23,11 @@ %define mappedStackEnd 0xFFBFFFFF %define originalPageTable 0x503000 +ebxStart: db 0x00000000 + global _start _start: + mov [ebxStart], ebx mov esp, stackEnd lgdt [gdt32.end] mov ax, 16 @@ -35,7 +37,7 @@ mov fs, ax mov gs, ax jmp 0x08:.setupPaging -.setupPaging +.setupPaging: mov eax, pageDirectory mov ebx, originalPageTable mov ecx, 0 @@ -114,8 +116,10 @@ section .text higherKernelEntry: -.cleanOriginalEntryCode + mov ebx, [ebxStart] + push ebx +.cleanOriginalEntryCode: mov eax, 0xFF800000 mov dword [eax], 0 call kernelMain - jmp $ \ No newline at end of file + jmp $ diff --git a/src/kernel/include/memory.h b/src/kernel/include/memory.h index c5c47c0..1d40818 100644 --- a/src/kernel/include/memory.h +++ b/src/kernel/include/memory.h @@ -4,7 +4,8 @@ #include extern void setupMemory(); -extern void reservePagesUntil(uint32_t endPageId); -extern void memset(uint8_t *target, uint8_t byte, uint32_t size); +extern void reservePagesUntilPhysical(uint32_t endPageId); +extern void memset(void *target, uint8_t byte, uint32_t size); +extern void *kernelMapPhysical(void *address); #endif diff --git a/src/kernel/include/multiboot.h b/src/kernel/include/multiboot.h new file mode 100644 index 0000000..26c0f93 --- /dev/null +++ b/src/kernel/include/multiboot.h @@ -0,0 +1,48 @@ +#ifndef MULTIBOOT_H +#define MULTIBOOT_H + +#include + +// note: this structure supports more stuff, but I'm looking for the modules +// here. Look at +// https://android.googlesource.com/platform/external/grub/+/1650e5296608be8925d9831310c9ad3595fd6869/docs/multiboot.info +// for more info + +typedef enum { + BootCommandLineType = 1, + ModulesType = 3, + BasicMemoryInformationType = 4, + BiosBootDeviceType = 5, +} MultibootType; + +typedef struct { + uint32_t type; // multiboot type + uint32_t size; +} MultibootModuleInfo; + +typedef struct { + MultibootModuleInfo; + uint32_t memUpper; + uint32_t memLower; +} BasicMemoryInformation; + +typedef struct { + MultibootModuleInfo; + uint32_t biosDevice; + uint32_t partition; + uint32_t subPartition; +} BiosBootDevice; + +typedef struct { + MultibootModuleInfo; + char string[0]; +} BootCommandLine; + +typedef struct { + MultibootModuleInfo; + uint32_t moduleStart; + uint32_t moduleEnd; + char string[0]; +} Modules; + +#endif diff --git a/src/kernel/include/util.h b/src/kernel/include/util.h new file mode 100644 index 0000000..672e7dd --- /dev/null +++ b/src/kernel/include/util.h @@ -0,0 +1,7 @@ +#ifndef UTIL_H +#define UTIL_H + +#define U32(x) (uint32_t)(uintptr_t)(x) +#define PTR(x) (void *)(uintptr_t)(x) + +#endif diff --git a/src/kernel/main.c b/src/kernel/main.c index a7c59eb..3d19504 100644 --- a/src/kernel/main.c +++ b/src/kernel/main.c @@ -1,10 +1,11 @@ #include +#include #include -void *multibootInfo; // set by bootloader - -void kernelMain() { +void kernelMain(void *multibootInfo) { setupMemory(); + void *address = kernelMapPhysical(multibootInfo); + asm("mov %%eax, %0" ::"r"(address)); while (1) ; } diff --git a/src/kernel/memory/memory.c b/src/kernel/memory/memory.c index 6c4010a..0be4063 100644 --- a/src/kernel/memory/memory.c +++ b/src/kernel/memory/memory.c @@ -2,6 +2,6 @@ #include void setupMemory() { - reservePagesUntil(0x900); // address 0x900000, until the end of where the - // kernel data was mapped + reservePagesUntilPhysical(0x900); // address 0x900000, until the end of + // where the kernel data was mapped } diff --git a/src/kernel/memory/memset.c b/src/kernel/memory/memset.c index cbe1503..874cacc 100644 --- a/src/kernel/memory/memset.c +++ b/src/kernel/memory/memset.c @@ -1,6 +1,7 @@ #include -void memset(uint8_t *target, uint8_t byte, uint32_t size) { +void memset(void *_target, uint8_t byte, uint32_t size) { + uint8_t *target = _target; for (uint32_t i = 0; i < size; i++) { *target = byte; target++; diff --git a/.gitignore b/.gitignore index c766352..8998d08 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,7 @@ build rootfs/boot/kernel +rootfs/bin +rootfs/initrd.tar .vscode *.log +initrd diff --git a/Makefile b/Makefile index 4614e12..801e89e 100644 --- a/Makefile +++ b/Makefile @@ -6,8 +6,6 @@ LD_FLAGS = -z max-page-size=0x1000 -T link.ld AS = nasm ASFlAGS = -felf32 -GENISO = genisoimage -GENISOFLAGS = -R -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4 -input-charset utf8 -quiet -boot-info-table -A tree-os EMU = qemu-system-x86_64 EMUFLAGS = -m 1G -drive format=raw,file=$(IMAGE_FILE) -no-reboot -no-shutdown -monitor stdio @@ -16,13 +14,13 @@ SOURCE_FILES := $(shell find src/kernel -name *.c -or -name *.asm -or -name *.s) OBJS := $(SOURCE_FILES:%=$(BUILD_FOLDER)/%.o) USER_PROGRAMS := $(shell ls src/userland) -USER_PROGRAM_NAMES := $(USER_PROGRAMS:%=rootfs/%) +USER_PROGRAM_NAMES := $(USER_PROGRAMS:%=initrd/%) run: $(IMAGE_FILE) @echo "starting qemu" @$(EMU) $(EMUFLAGS) -$(IMAGE_FILE): rootfs/boot/kernel $(USER_PROGRAM_NAMES) +$(IMAGE_FILE): rootfs/boot/kernel rootfs/initrd.tar echo "creating the iso image" dd if=/dev/zero of=$(IMAGE_FILE) bs=512 count=32768 &&\ printf "n\np\n1\n\n\na\nw\n" | fdisk $(IMAGE_FILE) &&\ @@ -34,13 +32,15 @@ sudo mount $$loop1 /mnt &&\ sudo grub-install --root-directory=/mnt --no-floppy --modules="normal part_msdos multiboot" $$loop0 &&\ sudo cp -RT rootfs/ /mnt &&\ - sudo rm -r /mnt/boot/grub/fonts &&\ sync &&\ sudo umount /mnt &&\ sudo losetup -d $$loop0 &&\ sudo losetup -d $$loop1 -rootfs/boot/kernel: $(OBJS) +rootfs/initrd.tar: $(USER_PROGRAM_NAMES) + tar cvf rootfs/initrd.tar initrd/ + +rootfs/boot/kernel: $(OBJS) link.ld @echo "linking" @$(LD) $(LD_FLAGS) -o $@ $(OBJS) @@ -59,14 +59,10 @@ @mkdir -p $(dir $@) @$(CC) $(CCFLAGS) -r $< -o $@ -rootfs/%: src/userland/% iso/modules +initrd/%: src/userland/% @echo "compiling userspace program $<" @make -C $< clean: @echo "clearing build folder" - @rm -r $(BUILD_FOLDER) tree-os.iso - -cleanELF: - @echo "clearing the elf file" - @rm iso/boot/tree-os.elf + @rm -r $(BUILD_FOLDER) diff --git a/link.ld b/link.ld index 05b49c4..6f0a9ee 100644 --- a/link.ld +++ b/link.ld @@ -7,7 +7,6 @@ .boot : { *(.boot) } - bootEnd = .; . += 0xFFB00000; .text : AT(ADDR(.text) - 0xFFB00000) { @@ -24,5 +23,11 @@ .bss :AT(ADDR(.bss) - 0xFFB00000) { *(.bss) + . = ALIGN(4M); + } + + . = 0x500000; + .kernelReserve :AT(0x500000) { + . += 0x400000; } } diff --git a/rootfs/boot/grub/grub.cfg b/rootfs/boot/grub/grub.cfg index c3394c2..2470bcc 100644 --- a/rootfs/boot/grub/grub.cfg +++ b/rootfs/boot/grub/grub.cfg @@ -3,5 +3,6 @@ menuentry "honey os" { multiboot2 /boot/kernel + module2 /initrd.tar boot } diff --git a/src/kernel/boot/boot.asm b/src/kernel/boot/boot.asm index 2288daa..dc00a9d 100644 --- a/src/kernel/boot/boot.asm +++ b/src/kernel/boot/boot.asm @@ -14,7 +14,6 @@ .end: extern kernelMain -extern multibootInfo %define pageDirectory 0x500000 %define kernelPageTable 0x501000 @@ -24,8 +23,11 @@ %define mappedStackEnd 0xFFBFFFFF %define originalPageTable 0x503000 +ebxStart: db 0x00000000 + global _start _start: + mov [ebxStart], ebx mov esp, stackEnd lgdt [gdt32.end] mov ax, 16 @@ -35,7 +37,7 @@ mov fs, ax mov gs, ax jmp 0x08:.setupPaging -.setupPaging +.setupPaging: mov eax, pageDirectory mov ebx, originalPageTable mov ecx, 0 @@ -114,8 +116,10 @@ section .text higherKernelEntry: -.cleanOriginalEntryCode + mov ebx, [ebxStart] + push ebx +.cleanOriginalEntryCode: mov eax, 0xFF800000 mov dword [eax], 0 call kernelMain - jmp $ \ No newline at end of file + jmp $ diff --git a/src/kernel/include/memory.h b/src/kernel/include/memory.h index c5c47c0..1d40818 100644 --- a/src/kernel/include/memory.h +++ b/src/kernel/include/memory.h @@ -4,7 +4,8 @@ #include extern void setupMemory(); -extern void reservePagesUntil(uint32_t endPageId); -extern void memset(uint8_t *target, uint8_t byte, uint32_t size); +extern void reservePagesUntilPhysical(uint32_t endPageId); +extern void memset(void *target, uint8_t byte, uint32_t size); +extern void *kernelMapPhysical(void *address); #endif diff --git a/src/kernel/include/multiboot.h b/src/kernel/include/multiboot.h new file mode 100644 index 0000000..26c0f93 --- /dev/null +++ b/src/kernel/include/multiboot.h @@ -0,0 +1,48 @@ +#ifndef MULTIBOOT_H +#define MULTIBOOT_H + +#include + +// note: this structure supports more stuff, but I'm looking for the modules +// here. Look at +// https://android.googlesource.com/platform/external/grub/+/1650e5296608be8925d9831310c9ad3595fd6869/docs/multiboot.info +// for more info + +typedef enum { + BootCommandLineType = 1, + ModulesType = 3, + BasicMemoryInformationType = 4, + BiosBootDeviceType = 5, +} MultibootType; + +typedef struct { + uint32_t type; // multiboot type + uint32_t size; +} MultibootModuleInfo; + +typedef struct { + MultibootModuleInfo; + uint32_t memUpper; + uint32_t memLower; +} BasicMemoryInformation; + +typedef struct { + MultibootModuleInfo; + uint32_t biosDevice; + uint32_t partition; + uint32_t subPartition; +} BiosBootDevice; + +typedef struct { + MultibootModuleInfo; + char string[0]; +} BootCommandLine; + +typedef struct { + MultibootModuleInfo; + uint32_t moduleStart; + uint32_t moduleEnd; + char string[0]; +} Modules; + +#endif diff --git a/src/kernel/include/util.h b/src/kernel/include/util.h new file mode 100644 index 0000000..672e7dd --- /dev/null +++ b/src/kernel/include/util.h @@ -0,0 +1,7 @@ +#ifndef UTIL_H +#define UTIL_H + +#define U32(x) (uint32_t)(uintptr_t)(x) +#define PTR(x) (void *)(uintptr_t)(x) + +#endif diff --git a/src/kernel/main.c b/src/kernel/main.c index a7c59eb..3d19504 100644 --- a/src/kernel/main.c +++ b/src/kernel/main.c @@ -1,10 +1,11 @@ #include +#include #include -void *multibootInfo; // set by bootloader - -void kernelMain() { +void kernelMain(void *multibootInfo) { setupMemory(); + void *address = kernelMapPhysical(multibootInfo); + asm("mov %%eax, %0" ::"r"(address)); while (1) ; } diff --git a/src/kernel/memory/memory.c b/src/kernel/memory/memory.c index 6c4010a..0be4063 100644 --- a/src/kernel/memory/memory.c +++ b/src/kernel/memory/memory.c @@ -2,6 +2,6 @@ #include void setupMemory() { - reservePagesUntil(0x900); // address 0x900000, until the end of where the - // kernel data was mapped + reservePagesUntilPhysical(0x900); // address 0x900000, until the end of + // where the kernel data was mapped } diff --git a/src/kernel/memory/memset.c b/src/kernel/memory/memset.c index cbe1503..874cacc 100644 --- a/src/kernel/memory/memset.c +++ b/src/kernel/memory/memset.c @@ -1,6 +1,7 @@ #include -void memset(uint8_t *target, uint8_t byte, uint32_t size) { +void memset(void *_target, uint8_t byte, uint32_t size) { + uint8_t *target = _target; for (uint32_t i = 0; i < size; i++) { *target = byte; target++; diff --git a/src/kernel/memory/paging.c b/src/kernel/memory/paging.c index d68efa7..cf36e66 100644 --- a/src/kernel/memory/paging.c +++ b/src/kernel/memory/paging.c @@ -1,29 +1,112 @@ #include "paging.h" #include +#include -PageDirectoryEntry *kernelDirectory = (void *)0xFF800000; -PageTableEntry *kernelPageTable = (void *)0xFF801000; -PageTableEntry *kernelDataPageTable = (void *)0xFF802000; -uint32_t *isPageAllocated = (void *)0xFF803000; -uint32_t *isPageAllocatedCoarse = (void *)0xFF843000; -uint32_t pageSearchStart; +PageDirectoryEntry *kernelDirectory; +PageTableEntry *kernelCodePageTable, *kernelDataPageTable, *kernelUtilityPages; -void reservePage(uint32_t pageId); +PagingInfo *physicalPages, *kernelVirtualPages; -void reservePagesUntil(uint32_t endPageId) { - memset(isPageAllocated, 0, 0x40000); - memset(isPageAllocatedCoarse, 0, 0x10000); - for (uint32_t i = 0; i < endPageId; i++) { - reservePage(i); +void reservePage(PagingInfo *info, uint32_t pageId); + +void *kernelGetVirtualAddress(void *_address) { + uint32_t address = (uint32_t)(uintptr_t)_address; + if (address < 0x100000) { + return 0; } - pageSearchStart = endPageId; + if (address <= 0x500000) { + return _address + 0xFFC00000 - 0x100000; + } + if (address <= 0x900000) { + return _address + 0xFF800000 - 0x500000; + } + return 0; } -void reservePage(uint32_t pageId) { - uint32_t coarsePosition = pageId / 32; - isPageAllocated[coarsePosition] |= 1 << (pageId % 32); - if (isPageAllocated[coarsePosition] == ~0) { - isPageAllocatedCoarse[coarsePosition / 32] |= 1 - << (coarsePosition % 32); +void *getPhysicalAddress(void *address, PageDirectoryEntry *pageDirectory) { + VirtualAddress *virtual = (void *)&address; + uint32_t pageTableLocation = + pageDirectory[virtual->pageDirectoryIndex].pageTableID; + PageTableEntry *pageTable = PTR(pageTableLocation << 12); + pageTable = kernelGetVirtualAddress(pageTable); + uint32_t pageBase = pageTable[virtual->pageTableIndex].targetAddress; + return PTR(pageBase << 12 | virtual->pageOffset); +} + +void mapDirectoryEntry(PageDirectoryEntry *directory, uint32_t pageTableIndex, + PageTableEntry *pageTable, PagingInfo *pagingInfo) { + directory[pageTableIndex].pageTableID = + U32(getPhysicalAddress(pageTable, directory)) >> 12; + directory[pageTableIndex].writable = 1; + directory[pageTableIndex].present = 1; + pagingInfo->isPageTableInUse[pageTableIndex / 32] |= + 1 << (pageTableIndex % 32); +} + +void reservePagesUntilPhysical(uint32_t endPageId) { + void *buffer = (void *)0xFF800000; + kernelDirectory = buffer; + memset(kernelDirectory, 0, 0xFF8); + buffer += 0x1000; + kernelCodePageTable = buffer; + buffer += 0x1000; + kernelDataPageTable = buffer; + buffer += 0x1000; + kernelUtilityPages = buffer; + buffer += 0x1000; + physicalPages = buffer; + buffer += sizeof(PagingInfo); + kernelVirtualPages = buffer; + buffer += sizeof(PagingInfo); + memset(physicalPages, 0, 2 * sizeof(PagingInfo)); + for (uint32_t i = 0; i < endPageId; i++) { + reservePage(physicalPages, i); } + for (uint32_t i = 0; i < 0x800; i++) { + reservePage(kernelVirtualPages, i + 0xFF800); + } + memset(kernelUtilityPages, 0, 0x1000); + mapDirectoryEntry(kernelDirectory, 0, kernelUtilityPages, + kernelVirtualPages); + physicalPages->pageSearchStart = endPageId; +} + +void reservePage(PagingInfo *info, uint32_t pageId) { + uint32_t coarsePosition = pageId / 32; + info->isPageAllocated[coarsePosition] |= 1 << (pageId % 32); + if (info->isPageAllocated[coarsePosition] == ~0) { + info->isPageAllocatedCoarse[coarsePosition / 32] |= + 1 << (coarsePosition % 32); + } +} + +uint32_t findPage(PagingInfo *info) { + for (uint32_t veryCoarse = info->pageSearchStart / 1024;; veryCoarse++) { + if (info->isPageAllocatedCoarse[veryCoarse] == ~0) { + continue; + } + for (uint8_t coarse = 0; coarse < 32; coarse++) { + if (info->isPageAllocatedCoarse[veryCoarse] & (1 << coarse)) { + continue; + } + uint32_t coarsePageId = (veryCoarse * 32 + coarse); + for (uint8_t fine = 0; fine < 32; fine++) { + if (info->isPageAllocated[coarsePageId] & (1 << fine)) { + continue; + } + return coarsePageId * 32 + fine; + } + } + } +} + +void *kernelMapPhysical(void *address) { + uint32_t physicalPage = U32(address) >> 12; + reservePage(physicalPages, physicalPage); + uint32_t virtualPage = findPage(kernelVirtualPages); + reservePage(kernelVirtualPages, virtualPage); + kernelUtilityPages[virtualPage].targetAddress = physicalPage; + kernelUtilityPages[virtualPage].writable = 1; + kernelUtilityPages[virtualPage].present = 1; + return PTR((virtualPage << 12) + (U32(address) & 0xFFF)); } diff --git a/.gitignore b/.gitignore index c766352..8998d08 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,7 @@ build rootfs/boot/kernel +rootfs/bin +rootfs/initrd.tar .vscode *.log +initrd diff --git a/Makefile b/Makefile index 4614e12..801e89e 100644 --- a/Makefile +++ b/Makefile @@ -6,8 +6,6 @@ LD_FLAGS = -z max-page-size=0x1000 -T link.ld AS = nasm ASFlAGS = -felf32 -GENISO = genisoimage -GENISOFLAGS = -R -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4 -input-charset utf8 -quiet -boot-info-table -A tree-os EMU = qemu-system-x86_64 EMUFLAGS = -m 1G -drive format=raw,file=$(IMAGE_FILE) -no-reboot -no-shutdown -monitor stdio @@ -16,13 +14,13 @@ SOURCE_FILES := $(shell find src/kernel -name *.c -or -name *.asm -or -name *.s) OBJS := $(SOURCE_FILES:%=$(BUILD_FOLDER)/%.o) USER_PROGRAMS := $(shell ls src/userland) -USER_PROGRAM_NAMES := $(USER_PROGRAMS:%=rootfs/%) +USER_PROGRAM_NAMES := $(USER_PROGRAMS:%=initrd/%) run: $(IMAGE_FILE) @echo "starting qemu" @$(EMU) $(EMUFLAGS) -$(IMAGE_FILE): rootfs/boot/kernel $(USER_PROGRAM_NAMES) +$(IMAGE_FILE): rootfs/boot/kernel rootfs/initrd.tar echo "creating the iso image" dd if=/dev/zero of=$(IMAGE_FILE) bs=512 count=32768 &&\ printf "n\np\n1\n\n\na\nw\n" | fdisk $(IMAGE_FILE) &&\ @@ -34,13 +32,15 @@ sudo mount $$loop1 /mnt &&\ sudo grub-install --root-directory=/mnt --no-floppy --modules="normal part_msdos multiboot" $$loop0 &&\ sudo cp -RT rootfs/ /mnt &&\ - sudo rm -r /mnt/boot/grub/fonts &&\ sync &&\ sudo umount /mnt &&\ sudo losetup -d $$loop0 &&\ sudo losetup -d $$loop1 -rootfs/boot/kernel: $(OBJS) +rootfs/initrd.tar: $(USER_PROGRAM_NAMES) + tar cvf rootfs/initrd.tar initrd/ + +rootfs/boot/kernel: $(OBJS) link.ld @echo "linking" @$(LD) $(LD_FLAGS) -o $@ $(OBJS) @@ -59,14 +59,10 @@ @mkdir -p $(dir $@) @$(CC) $(CCFLAGS) -r $< -o $@ -rootfs/%: src/userland/% iso/modules +initrd/%: src/userland/% @echo "compiling userspace program $<" @make -C $< clean: @echo "clearing build folder" - @rm -r $(BUILD_FOLDER) tree-os.iso - -cleanELF: - @echo "clearing the elf file" - @rm iso/boot/tree-os.elf + @rm -r $(BUILD_FOLDER) diff --git a/link.ld b/link.ld index 05b49c4..6f0a9ee 100644 --- a/link.ld +++ b/link.ld @@ -7,7 +7,6 @@ .boot : { *(.boot) } - bootEnd = .; . += 0xFFB00000; .text : AT(ADDR(.text) - 0xFFB00000) { @@ -24,5 +23,11 @@ .bss :AT(ADDR(.bss) - 0xFFB00000) { *(.bss) + . = ALIGN(4M); + } + + . = 0x500000; + .kernelReserve :AT(0x500000) { + . += 0x400000; } } diff --git a/rootfs/boot/grub/grub.cfg b/rootfs/boot/grub/grub.cfg index c3394c2..2470bcc 100644 --- a/rootfs/boot/grub/grub.cfg +++ b/rootfs/boot/grub/grub.cfg @@ -3,5 +3,6 @@ menuentry "honey os" { multiboot2 /boot/kernel + module2 /initrd.tar boot } diff --git a/src/kernel/boot/boot.asm b/src/kernel/boot/boot.asm index 2288daa..dc00a9d 100644 --- a/src/kernel/boot/boot.asm +++ b/src/kernel/boot/boot.asm @@ -14,7 +14,6 @@ .end: extern kernelMain -extern multibootInfo %define pageDirectory 0x500000 %define kernelPageTable 0x501000 @@ -24,8 +23,11 @@ %define mappedStackEnd 0xFFBFFFFF %define originalPageTable 0x503000 +ebxStart: db 0x00000000 + global _start _start: + mov [ebxStart], ebx mov esp, stackEnd lgdt [gdt32.end] mov ax, 16 @@ -35,7 +37,7 @@ mov fs, ax mov gs, ax jmp 0x08:.setupPaging -.setupPaging +.setupPaging: mov eax, pageDirectory mov ebx, originalPageTable mov ecx, 0 @@ -114,8 +116,10 @@ section .text higherKernelEntry: -.cleanOriginalEntryCode + mov ebx, [ebxStart] + push ebx +.cleanOriginalEntryCode: mov eax, 0xFF800000 mov dword [eax], 0 call kernelMain - jmp $ \ No newline at end of file + jmp $ diff --git a/src/kernel/include/memory.h b/src/kernel/include/memory.h index c5c47c0..1d40818 100644 --- a/src/kernel/include/memory.h +++ b/src/kernel/include/memory.h @@ -4,7 +4,8 @@ #include extern void setupMemory(); -extern void reservePagesUntil(uint32_t endPageId); -extern void memset(uint8_t *target, uint8_t byte, uint32_t size); +extern void reservePagesUntilPhysical(uint32_t endPageId); +extern void memset(void *target, uint8_t byte, uint32_t size); +extern void *kernelMapPhysical(void *address); #endif diff --git a/src/kernel/include/multiboot.h b/src/kernel/include/multiboot.h new file mode 100644 index 0000000..26c0f93 --- /dev/null +++ b/src/kernel/include/multiboot.h @@ -0,0 +1,48 @@ +#ifndef MULTIBOOT_H +#define MULTIBOOT_H + +#include + +// note: this structure supports more stuff, but I'm looking for the modules +// here. Look at +// https://android.googlesource.com/platform/external/grub/+/1650e5296608be8925d9831310c9ad3595fd6869/docs/multiboot.info +// for more info + +typedef enum { + BootCommandLineType = 1, + ModulesType = 3, + BasicMemoryInformationType = 4, + BiosBootDeviceType = 5, +} MultibootType; + +typedef struct { + uint32_t type; // multiboot type + uint32_t size; +} MultibootModuleInfo; + +typedef struct { + MultibootModuleInfo; + uint32_t memUpper; + uint32_t memLower; +} BasicMemoryInformation; + +typedef struct { + MultibootModuleInfo; + uint32_t biosDevice; + uint32_t partition; + uint32_t subPartition; +} BiosBootDevice; + +typedef struct { + MultibootModuleInfo; + char string[0]; +} BootCommandLine; + +typedef struct { + MultibootModuleInfo; + uint32_t moduleStart; + uint32_t moduleEnd; + char string[0]; +} Modules; + +#endif diff --git a/src/kernel/include/util.h b/src/kernel/include/util.h new file mode 100644 index 0000000..672e7dd --- /dev/null +++ b/src/kernel/include/util.h @@ -0,0 +1,7 @@ +#ifndef UTIL_H +#define UTIL_H + +#define U32(x) (uint32_t)(uintptr_t)(x) +#define PTR(x) (void *)(uintptr_t)(x) + +#endif diff --git a/src/kernel/main.c b/src/kernel/main.c index a7c59eb..3d19504 100644 --- a/src/kernel/main.c +++ b/src/kernel/main.c @@ -1,10 +1,11 @@ #include +#include #include -void *multibootInfo; // set by bootloader - -void kernelMain() { +void kernelMain(void *multibootInfo) { setupMemory(); + void *address = kernelMapPhysical(multibootInfo); + asm("mov %%eax, %0" ::"r"(address)); while (1) ; } diff --git a/src/kernel/memory/memory.c b/src/kernel/memory/memory.c index 6c4010a..0be4063 100644 --- a/src/kernel/memory/memory.c +++ b/src/kernel/memory/memory.c @@ -2,6 +2,6 @@ #include void setupMemory() { - reservePagesUntil(0x900); // address 0x900000, until the end of where the - // kernel data was mapped + reservePagesUntilPhysical(0x900); // address 0x900000, until the end of + // where the kernel data was mapped } diff --git a/src/kernel/memory/memset.c b/src/kernel/memory/memset.c index cbe1503..874cacc 100644 --- a/src/kernel/memory/memset.c +++ b/src/kernel/memory/memset.c @@ -1,6 +1,7 @@ #include -void memset(uint8_t *target, uint8_t byte, uint32_t size) { +void memset(void *_target, uint8_t byte, uint32_t size) { + uint8_t *target = _target; for (uint32_t i = 0; i < size; i++) { *target = byte; target++; diff --git a/src/kernel/memory/paging.c b/src/kernel/memory/paging.c index d68efa7..cf36e66 100644 --- a/src/kernel/memory/paging.c +++ b/src/kernel/memory/paging.c @@ -1,29 +1,112 @@ #include "paging.h" #include +#include -PageDirectoryEntry *kernelDirectory = (void *)0xFF800000; -PageTableEntry *kernelPageTable = (void *)0xFF801000; -PageTableEntry *kernelDataPageTable = (void *)0xFF802000; -uint32_t *isPageAllocated = (void *)0xFF803000; -uint32_t *isPageAllocatedCoarse = (void *)0xFF843000; -uint32_t pageSearchStart; +PageDirectoryEntry *kernelDirectory; +PageTableEntry *kernelCodePageTable, *kernelDataPageTable, *kernelUtilityPages; -void reservePage(uint32_t pageId); +PagingInfo *physicalPages, *kernelVirtualPages; -void reservePagesUntil(uint32_t endPageId) { - memset(isPageAllocated, 0, 0x40000); - memset(isPageAllocatedCoarse, 0, 0x10000); - for (uint32_t i = 0; i < endPageId; i++) { - reservePage(i); +void reservePage(PagingInfo *info, uint32_t pageId); + +void *kernelGetVirtualAddress(void *_address) { + uint32_t address = (uint32_t)(uintptr_t)_address; + if (address < 0x100000) { + return 0; } - pageSearchStart = endPageId; + if (address <= 0x500000) { + return _address + 0xFFC00000 - 0x100000; + } + if (address <= 0x900000) { + return _address + 0xFF800000 - 0x500000; + } + return 0; } -void reservePage(uint32_t pageId) { - uint32_t coarsePosition = pageId / 32; - isPageAllocated[coarsePosition] |= 1 << (pageId % 32); - if (isPageAllocated[coarsePosition] == ~0) { - isPageAllocatedCoarse[coarsePosition / 32] |= 1 - << (coarsePosition % 32); +void *getPhysicalAddress(void *address, PageDirectoryEntry *pageDirectory) { + VirtualAddress *virtual = (void *)&address; + uint32_t pageTableLocation = + pageDirectory[virtual->pageDirectoryIndex].pageTableID; + PageTableEntry *pageTable = PTR(pageTableLocation << 12); + pageTable = kernelGetVirtualAddress(pageTable); + uint32_t pageBase = pageTable[virtual->pageTableIndex].targetAddress; + return PTR(pageBase << 12 | virtual->pageOffset); +} + +void mapDirectoryEntry(PageDirectoryEntry *directory, uint32_t pageTableIndex, + PageTableEntry *pageTable, PagingInfo *pagingInfo) { + directory[pageTableIndex].pageTableID = + U32(getPhysicalAddress(pageTable, directory)) >> 12; + directory[pageTableIndex].writable = 1; + directory[pageTableIndex].present = 1; + pagingInfo->isPageTableInUse[pageTableIndex / 32] |= + 1 << (pageTableIndex % 32); +} + +void reservePagesUntilPhysical(uint32_t endPageId) { + void *buffer = (void *)0xFF800000; + kernelDirectory = buffer; + memset(kernelDirectory, 0, 0xFF8); + buffer += 0x1000; + kernelCodePageTable = buffer; + buffer += 0x1000; + kernelDataPageTable = buffer; + buffer += 0x1000; + kernelUtilityPages = buffer; + buffer += 0x1000; + physicalPages = buffer; + buffer += sizeof(PagingInfo); + kernelVirtualPages = buffer; + buffer += sizeof(PagingInfo); + memset(physicalPages, 0, 2 * sizeof(PagingInfo)); + for (uint32_t i = 0; i < endPageId; i++) { + reservePage(physicalPages, i); } + for (uint32_t i = 0; i < 0x800; i++) { + reservePage(kernelVirtualPages, i + 0xFF800); + } + memset(kernelUtilityPages, 0, 0x1000); + mapDirectoryEntry(kernelDirectory, 0, kernelUtilityPages, + kernelVirtualPages); + physicalPages->pageSearchStart = endPageId; +} + +void reservePage(PagingInfo *info, uint32_t pageId) { + uint32_t coarsePosition = pageId / 32; + info->isPageAllocated[coarsePosition] |= 1 << (pageId % 32); + if (info->isPageAllocated[coarsePosition] == ~0) { + info->isPageAllocatedCoarse[coarsePosition / 32] |= + 1 << (coarsePosition % 32); + } +} + +uint32_t findPage(PagingInfo *info) { + for (uint32_t veryCoarse = info->pageSearchStart / 1024;; veryCoarse++) { + if (info->isPageAllocatedCoarse[veryCoarse] == ~0) { + continue; + } + for (uint8_t coarse = 0; coarse < 32; coarse++) { + if (info->isPageAllocatedCoarse[veryCoarse] & (1 << coarse)) { + continue; + } + uint32_t coarsePageId = (veryCoarse * 32 + coarse); + for (uint8_t fine = 0; fine < 32; fine++) { + if (info->isPageAllocated[coarsePageId] & (1 << fine)) { + continue; + } + return coarsePageId * 32 + fine; + } + } + } +} + +void *kernelMapPhysical(void *address) { + uint32_t physicalPage = U32(address) >> 12; + reservePage(physicalPages, physicalPage); + uint32_t virtualPage = findPage(kernelVirtualPages); + reservePage(kernelVirtualPages, virtualPage); + kernelUtilityPages[virtualPage].targetAddress = physicalPage; + kernelUtilityPages[virtualPage].writable = 1; + kernelUtilityPages[virtualPage].present = 1; + return PTR((virtualPage << 12) + (U32(address) & 0xFFF)); } diff --git a/src/kernel/memory/paging.h b/src/kernel/memory/paging.h index 70dc0d0..208f670 100644 --- a/src/kernel/memory/paging.h +++ b/src/kernel/memory/paging.h @@ -12,8 +12,8 @@ uint32_t dirty : 1; uint32_t reserved2 : 2; uint32_t available : 3; - uint32_t pageTableID : 22; -} PageDirectoryEntry; + uint32_t pageTableID : 20; +} __attribute__((packed)) PageDirectoryEntry; typedef struct { uint32_t present : 1; @@ -27,6 +27,19 @@ uint32_t global : 1; uint32_t available : 3; uint32_t targetAddress : 20; -} PageTableEntry; +} __attribute__((packed)) PageTableEntry; + +typedef struct { + uint32_t isPageAllocated[0x8000]; + uint32_t isPageAllocatedCoarse[0x400]; + uint32_t isPageTableInUse[0x20]; + uint32_t pageSearchStart; +} PagingInfo; + +typedef struct { + uint32_t pageOffset : 12; + uint32_t pageTableIndex : 10; + uint32_t pageDirectoryIndex : 10; +} __attribute__((packed)) VirtualAddress; #endif diff --git a/.gitignore b/.gitignore index c766352..8998d08 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,7 @@ build rootfs/boot/kernel +rootfs/bin +rootfs/initrd.tar .vscode *.log +initrd diff --git a/Makefile b/Makefile index 4614e12..801e89e 100644 --- a/Makefile +++ b/Makefile @@ -6,8 +6,6 @@ LD_FLAGS = -z max-page-size=0x1000 -T link.ld AS = nasm ASFlAGS = -felf32 -GENISO = genisoimage -GENISOFLAGS = -R -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4 -input-charset utf8 -quiet -boot-info-table -A tree-os EMU = qemu-system-x86_64 EMUFLAGS = -m 1G -drive format=raw,file=$(IMAGE_FILE) -no-reboot -no-shutdown -monitor stdio @@ -16,13 +14,13 @@ SOURCE_FILES := $(shell find src/kernel -name *.c -or -name *.asm -or -name *.s) OBJS := $(SOURCE_FILES:%=$(BUILD_FOLDER)/%.o) USER_PROGRAMS := $(shell ls src/userland) -USER_PROGRAM_NAMES := $(USER_PROGRAMS:%=rootfs/%) +USER_PROGRAM_NAMES := $(USER_PROGRAMS:%=initrd/%) run: $(IMAGE_FILE) @echo "starting qemu" @$(EMU) $(EMUFLAGS) -$(IMAGE_FILE): rootfs/boot/kernel $(USER_PROGRAM_NAMES) +$(IMAGE_FILE): rootfs/boot/kernel rootfs/initrd.tar echo "creating the iso image" dd if=/dev/zero of=$(IMAGE_FILE) bs=512 count=32768 &&\ printf "n\np\n1\n\n\na\nw\n" | fdisk $(IMAGE_FILE) &&\ @@ -34,13 +32,15 @@ sudo mount $$loop1 /mnt &&\ sudo grub-install --root-directory=/mnt --no-floppy --modules="normal part_msdos multiboot" $$loop0 &&\ sudo cp -RT rootfs/ /mnt &&\ - sudo rm -r /mnt/boot/grub/fonts &&\ sync &&\ sudo umount /mnt &&\ sudo losetup -d $$loop0 &&\ sudo losetup -d $$loop1 -rootfs/boot/kernel: $(OBJS) +rootfs/initrd.tar: $(USER_PROGRAM_NAMES) + tar cvf rootfs/initrd.tar initrd/ + +rootfs/boot/kernel: $(OBJS) link.ld @echo "linking" @$(LD) $(LD_FLAGS) -o $@ $(OBJS) @@ -59,14 +59,10 @@ @mkdir -p $(dir $@) @$(CC) $(CCFLAGS) -r $< -o $@ -rootfs/%: src/userland/% iso/modules +initrd/%: src/userland/% @echo "compiling userspace program $<" @make -C $< clean: @echo "clearing build folder" - @rm -r $(BUILD_FOLDER) tree-os.iso - -cleanELF: - @echo "clearing the elf file" - @rm iso/boot/tree-os.elf + @rm -r $(BUILD_FOLDER) diff --git a/link.ld b/link.ld index 05b49c4..6f0a9ee 100644 --- a/link.ld +++ b/link.ld @@ -7,7 +7,6 @@ .boot : { *(.boot) } - bootEnd = .; . += 0xFFB00000; .text : AT(ADDR(.text) - 0xFFB00000) { @@ -24,5 +23,11 @@ .bss :AT(ADDR(.bss) - 0xFFB00000) { *(.bss) + . = ALIGN(4M); + } + + . = 0x500000; + .kernelReserve :AT(0x500000) { + . += 0x400000; } } diff --git a/rootfs/boot/grub/grub.cfg b/rootfs/boot/grub/grub.cfg index c3394c2..2470bcc 100644 --- a/rootfs/boot/grub/grub.cfg +++ b/rootfs/boot/grub/grub.cfg @@ -3,5 +3,6 @@ menuentry "honey os" { multiboot2 /boot/kernel + module2 /initrd.tar boot } diff --git a/src/kernel/boot/boot.asm b/src/kernel/boot/boot.asm index 2288daa..dc00a9d 100644 --- a/src/kernel/boot/boot.asm +++ b/src/kernel/boot/boot.asm @@ -14,7 +14,6 @@ .end: extern kernelMain -extern multibootInfo %define pageDirectory 0x500000 %define kernelPageTable 0x501000 @@ -24,8 +23,11 @@ %define mappedStackEnd 0xFFBFFFFF %define originalPageTable 0x503000 +ebxStart: db 0x00000000 + global _start _start: + mov [ebxStart], ebx mov esp, stackEnd lgdt [gdt32.end] mov ax, 16 @@ -35,7 +37,7 @@ mov fs, ax mov gs, ax jmp 0x08:.setupPaging -.setupPaging +.setupPaging: mov eax, pageDirectory mov ebx, originalPageTable mov ecx, 0 @@ -114,8 +116,10 @@ section .text higherKernelEntry: -.cleanOriginalEntryCode + mov ebx, [ebxStart] + push ebx +.cleanOriginalEntryCode: mov eax, 0xFF800000 mov dword [eax], 0 call kernelMain - jmp $ \ No newline at end of file + jmp $ diff --git a/src/kernel/include/memory.h b/src/kernel/include/memory.h index c5c47c0..1d40818 100644 --- a/src/kernel/include/memory.h +++ b/src/kernel/include/memory.h @@ -4,7 +4,8 @@ #include extern void setupMemory(); -extern void reservePagesUntil(uint32_t endPageId); -extern void memset(uint8_t *target, uint8_t byte, uint32_t size); +extern void reservePagesUntilPhysical(uint32_t endPageId); +extern void memset(void *target, uint8_t byte, uint32_t size); +extern void *kernelMapPhysical(void *address); #endif diff --git a/src/kernel/include/multiboot.h b/src/kernel/include/multiboot.h new file mode 100644 index 0000000..26c0f93 --- /dev/null +++ b/src/kernel/include/multiboot.h @@ -0,0 +1,48 @@ +#ifndef MULTIBOOT_H +#define MULTIBOOT_H + +#include + +// note: this structure supports more stuff, but I'm looking for the modules +// here. Look at +// https://android.googlesource.com/platform/external/grub/+/1650e5296608be8925d9831310c9ad3595fd6869/docs/multiboot.info +// for more info + +typedef enum { + BootCommandLineType = 1, + ModulesType = 3, + BasicMemoryInformationType = 4, + BiosBootDeviceType = 5, +} MultibootType; + +typedef struct { + uint32_t type; // multiboot type + uint32_t size; +} MultibootModuleInfo; + +typedef struct { + MultibootModuleInfo; + uint32_t memUpper; + uint32_t memLower; +} BasicMemoryInformation; + +typedef struct { + MultibootModuleInfo; + uint32_t biosDevice; + uint32_t partition; + uint32_t subPartition; +} BiosBootDevice; + +typedef struct { + MultibootModuleInfo; + char string[0]; +} BootCommandLine; + +typedef struct { + MultibootModuleInfo; + uint32_t moduleStart; + uint32_t moduleEnd; + char string[0]; +} Modules; + +#endif diff --git a/src/kernel/include/util.h b/src/kernel/include/util.h new file mode 100644 index 0000000..672e7dd --- /dev/null +++ b/src/kernel/include/util.h @@ -0,0 +1,7 @@ +#ifndef UTIL_H +#define UTIL_H + +#define U32(x) (uint32_t)(uintptr_t)(x) +#define PTR(x) (void *)(uintptr_t)(x) + +#endif diff --git a/src/kernel/main.c b/src/kernel/main.c index a7c59eb..3d19504 100644 --- a/src/kernel/main.c +++ b/src/kernel/main.c @@ -1,10 +1,11 @@ #include +#include #include -void *multibootInfo; // set by bootloader - -void kernelMain() { +void kernelMain(void *multibootInfo) { setupMemory(); + void *address = kernelMapPhysical(multibootInfo); + asm("mov %%eax, %0" ::"r"(address)); while (1) ; } diff --git a/src/kernel/memory/memory.c b/src/kernel/memory/memory.c index 6c4010a..0be4063 100644 --- a/src/kernel/memory/memory.c +++ b/src/kernel/memory/memory.c @@ -2,6 +2,6 @@ #include void setupMemory() { - reservePagesUntil(0x900); // address 0x900000, until the end of where the - // kernel data was mapped + reservePagesUntilPhysical(0x900); // address 0x900000, until the end of + // where the kernel data was mapped } diff --git a/src/kernel/memory/memset.c b/src/kernel/memory/memset.c index cbe1503..874cacc 100644 --- a/src/kernel/memory/memset.c +++ b/src/kernel/memory/memset.c @@ -1,6 +1,7 @@ #include -void memset(uint8_t *target, uint8_t byte, uint32_t size) { +void memset(void *_target, uint8_t byte, uint32_t size) { + uint8_t *target = _target; for (uint32_t i = 0; i < size; i++) { *target = byte; target++; diff --git a/src/kernel/memory/paging.c b/src/kernel/memory/paging.c index d68efa7..cf36e66 100644 --- a/src/kernel/memory/paging.c +++ b/src/kernel/memory/paging.c @@ -1,29 +1,112 @@ #include "paging.h" #include +#include -PageDirectoryEntry *kernelDirectory = (void *)0xFF800000; -PageTableEntry *kernelPageTable = (void *)0xFF801000; -PageTableEntry *kernelDataPageTable = (void *)0xFF802000; -uint32_t *isPageAllocated = (void *)0xFF803000; -uint32_t *isPageAllocatedCoarse = (void *)0xFF843000; -uint32_t pageSearchStart; +PageDirectoryEntry *kernelDirectory; +PageTableEntry *kernelCodePageTable, *kernelDataPageTable, *kernelUtilityPages; -void reservePage(uint32_t pageId); +PagingInfo *physicalPages, *kernelVirtualPages; -void reservePagesUntil(uint32_t endPageId) { - memset(isPageAllocated, 0, 0x40000); - memset(isPageAllocatedCoarse, 0, 0x10000); - for (uint32_t i = 0; i < endPageId; i++) { - reservePage(i); +void reservePage(PagingInfo *info, uint32_t pageId); + +void *kernelGetVirtualAddress(void *_address) { + uint32_t address = (uint32_t)(uintptr_t)_address; + if (address < 0x100000) { + return 0; } - pageSearchStart = endPageId; + if (address <= 0x500000) { + return _address + 0xFFC00000 - 0x100000; + } + if (address <= 0x900000) { + return _address + 0xFF800000 - 0x500000; + } + return 0; } -void reservePage(uint32_t pageId) { - uint32_t coarsePosition = pageId / 32; - isPageAllocated[coarsePosition] |= 1 << (pageId % 32); - if (isPageAllocated[coarsePosition] == ~0) { - isPageAllocatedCoarse[coarsePosition / 32] |= 1 - << (coarsePosition % 32); +void *getPhysicalAddress(void *address, PageDirectoryEntry *pageDirectory) { + VirtualAddress *virtual = (void *)&address; + uint32_t pageTableLocation = + pageDirectory[virtual->pageDirectoryIndex].pageTableID; + PageTableEntry *pageTable = PTR(pageTableLocation << 12); + pageTable = kernelGetVirtualAddress(pageTable); + uint32_t pageBase = pageTable[virtual->pageTableIndex].targetAddress; + return PTR(pageBase << 12 | virtual->pageOffset); +} + +void mapDirectoryEntry(PageDirectoryEntry *directory, uint32_t pageTableIndex, + PageTableEntry *pageTable, PagingInfo *pagingInfo) { + directory[pageTableIndex].pageTableID = + U32(getPhysicalAddress(pageTable, directory)) >> 12; + directory[pageTableIndex].writable = 1; + directory[pageTableIndex].present = 1; + pagingInfo->isPageTableInUse[pageTableIndex / 32] |= + 1 << (pageTableIndex % 32); +} + +void reservePagesUntilPhysical(uint32_t endPageId) { + void *buffer = (void *)0xFF800000; + kernelDirectory = buffer; + memset(kernelDirectory, 0, 0xFF8); + buffer += 0x1000; + kernelCodePageTable = buffer; + buffer += 0x1000; + kernelDataPageTable = buffer; + buffer += 0x1000; + kernelUtilityPages = buffer; + buffer += 0x1000; + physicalPages = buffer; + buffer += sizeof(PagingInfo); + kernelVirtualPages = buffer; + buffer += sizeof(PagingInfo); + memset(physicalPages, 0, 2 * sizeof(PagingInfo)); + for (uint32_t i = 0; i < endPageId; i++) { + reservePage(physicalPages, i); } + for (uint32_t i = 0; i < 0x800; i++) { + reservePage(kernelVirtualPages, i + 0xFF800); + } + memset(kernelUtilityPages, 0, 0x1000); + mapDirectoryEntry(kernelDirectory, 0, kernelUtilityPages, + kernelVirtualPages); + physicalPages->pageSearchStart = endPageId; +} + +void reservePage(PagingInfo *info, uint32_t pageId) { + uint32_t coarsePosition = pageId / 32; + info->isPageAllocated[coarsePosition] |= 1 << (pageId % 32); + if (info->isPageAllocated[coarsePosition] == ~0) { + info->isPageAllocatedCoarse[coarsePosition / 32] |= + 1 << (coarsePosition % 32); + } +} + +uint32_t findPage(PagingInfo *info) { + for (uint32_t veryCoarse = info->pageSearchStart / 1024;; veryCoarse++) { + if (info->isPageAllocatedCoarse[veryCoarse] == ~0) { + continue; + } + for (uint8_t coarse = 0; coarse < 32; coarse++) { + if (info->isPageAllocatedCoarse[veryCoarse] & (1 << coarse)) { + continue; + } + uint32_t coarsePageId = (veryCoarse * 32 + coarse); + for (uint8_t fine = 0; fine < 32; fine++) { + if (info->isPageAllocated[coarsePageId] & (1 << fine)) { + continue; + } + return coarsePageId * 32 + fine; + } + } + } +} + +void *kernelMapPhysical(void *address) { + uint32_t physicalPage = U32(address) >> 12; + reservePage(physicalPages, physicalPage); + uint32_t virtualPage = findPage(kernelVirtualPages); + reservePage(kernelVirtualPages, virtualPage); + kernelUtilityPages[virtualPage].targetAddress = physicalPage; + kernelUtilityPages[virtualPage].writable = 1; + kernelUtilityPages[virtualPage].present = 1; + return PTR((virtualPage << 12) + (U32(address) & 0xFFF)); } diff --git a/src/kernel/memory/paging.h b/src/kernel/memory/paging.h index 70dc0d0..208f670 100644 --- a/src/kernel/memory/paging.h +++ b/src/kernel/memory/paging.h @@ -12,8 +12,8 @@ uint32_t dirty : 1; uint32_t reserved2 : 2; uint32_t available : 3; - uint32_t pageTableID : 22; -} PageDirectoryEntry; + uint32_t pageTableID : 20; +} __attribute__((packed)) PageDirectoryEntry; typedef struct { uint32_t present : 1; @@ -27,6 +27,19 @@ uint32_t global : 1; uint32_t available : 3; uint32_t targetAddress : 20; -} PageTableEntry; +} __attribute__((packed)) PageTableEntry; + +typedef struct { + uint32_t isPageAllocated[0x8000]; + uint32_t isPageAllocatedCoarse[0x400]; + uint32_t isPageTableInUse[0x20]; + uint32_t pageSearchStart; +} PagingInfo; + +typedef struct { + uint32_t pageOffset : 12; + uint32_t pageTableIndex : 10; + uint32_t pageDirectoryIndex : 10; +} __attribute__((packed)) VirtualAddress; #endif diff --git a/src/userland/loader/Makefile b/src/userland/loader/Makefile new file mode 100644 index 0000000..d6c7c6c --- /dev/null +++ b/src/userland/loader/Makefile @@ -0,0 +1,29 @@ +CC = i686-elf-gcc +CCFLAGS = -m32 -mtune=generic -ffreestanding -nostdlib -c -I ../../include -I include -Wno-discarded-qualifiers -fms-extensions -Wno-shift-count-overflow -O0 +LD = i686-elf-ld +LD_FLAGS = -z max-page-size=0x1000 +AS = nasm +ASFlAGS = -felf32 + +BUILD_FOLDER = build + +SOURCE_FILES := $(shell find . -name *.c -or -name *.asm -or -name *.s) +OBJS := $(SOURCE_FILES:%=$(BUILD_FOLDER)/%.o) + +../../../initrd/loader: $(OBJS) + @echo "linking user program loader" + @$(LD) $(LD_FLAGS) -o ../../../initrd/loader $(OBJS) + +$(BUILD_FOLDER)/%.asm.o: %.asm + @echo "asembling $<" + @mkdir -p $(dir $@) + @$(AS) $(ASFlAGS) $< -o $@ + +$(BUILD_FOLDER)/%.c.o: %.c + @echo "compiling $<" + @mkdir -p $(dir $@) + @$(CC) $(CCFLAGS) -r $< -o $@ + +clean: + @echo "clearing build folder" + @rm -r $(BUILD_FOLDER) diff --git a/.gitignore b/.gitignore index c766352..8998d08 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,7 @@ build rootfs/boot/kernel +rootfs/bin +rootfs/initrd.tar .vscode *.log +initrd diff --git a/Makefile b/Makefile index 4614e12..801e89e 100644 --- a/Makefile +++ b/Makefile @@ -6,8 +6,6 @@ LD_FLAGS = -z max-page-size=0x1000 -T link.ld AS = nasm ASFlAGS = -felf32 -GENISO = genisoimage -GENISOFLAGS = -R -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4 -input-charset utf8 -quiet -boot-info-table -A tree-os EMU = qemu-system-x86_64 EMUFLAGS = -m 1G -drive format=raw,file=$(IMAGE_FILE) -no-reboot -no-shutdown -monitor stdio @@ -16,13 +14,13 @@ SOURCE_FILES := $(shell find src/kernel -name *.c -or -name *.asm -or -name *.s) OBJS := $(SOURCE_FILES:%=$(BUILD_FOLDER)/%.o) USER_PROGRAMS := $(shell ls src/userland) -USER_PROGRAM_NAMES := $(USER_PROGRAMS:%=rootfs/%) +USER_PROGRAM_NAMES := $(USER_PROGRAMS:%=initrd/%) run: $(IMAGE_FILE) @echo "starting qemu" @$(EMU) $(EMUFLAGS) -$(IMAGE_FILE): rootfs/boot/kernel $(USER_PROGRAM_NAMES) +$(IMAGE_FILE): rootfs/boot/kernel rootfs/initrd.tar echo "creating the iso image" dd if=/dev/zero of=$(IMAGE_FILE) bs=512 count=32768 &&\ printf "n\np\n1\n\n\na\nw\n" | fdisk $(IMAGE_FILE) &&\ @@ -34,13 +32,15 @@ sudo mount $$loop1 /mnt &&\ sudo grub-install --root-directory=/mnt --no-floppy --modules="normal part_msdos multiboot" $$loop0 &&\ sudo cp -RT rootfs/ /mnt &&\ - sudo rm -r /mnt/boot/grub/fonts &&\ sync &&\ sudo umount /mnt &&\ sudo losetup -d $$loop0 &&\ sudo losetup -d $$loop1 -rootfs/boot/kernel: $(OBJS) +rootfs/initrd.tar: $(USER_PROGRAM_NAMES) + tar cvf rootfs/initrd.tar initrd/ + +rootfs/boot/kernel: $(OBJS) link.ld @echo "linking" @$(LD) $(LD_FLAGS) -o $@ $(OBJS) @@ -59,14 +59,10 @@ @mkdir -p $(dir $@) @$(CC) $(CCFLAGS) -r $< -o $@ -rootfs/%: src/userland/% iso/modules +initrd/%: src/userland/% @echo "compiling userspace program $<" @make -C $< clean: @echo "clearing build folder" - @rm -r $(BUILD_FOLDER) tree-os.iso - -cleanELF: - @echo "clearing the elf file" - @rm iso/boot/tree-os.elf + @rm -r $(BUILD_FOLDER) diff --git a/link.ld b/link.ld index 05b49c4..6f0a9ee 100644 --- a/link.ld +++ b/link.ld @@ -7,7 +7,6 @@ .boot : { *(.boot) } - bootEnd = .; . += 0xFFB00000; .text : AT(ADDR(.text) - 0xFFB00000) { @@ -24,5 +23,11 @@ .bss :AT(ADDR(.bss) - 0xFFB00000) { *(.bss) + . = ALIGN(4M); + } + + . = 0x500000; + .kernelReserve :AT(0x500000) { + . += 0x400000; } } diff --git a/rootfs/boot/grub/grub.cfg b/rootfs/boot/grub/grub.cfg index c3394c2..2470bcc 100644 --- a/rootfs/boot/grub/grub.cfg +++ b/rootfs/boot/grub/grub.cfg @@ -3,5 +3,6 @@ menuentry "honey os" { multiboot2 /boot/kernel + module2 /initrd.tar boot } diff --git a/src/kernel/boot/boot.asm b/src/kernel/boot/boot.asm index 2288daa..dc00a9d 100644 --- a/src/kernel/boot/boot.asm +++ b/src/kernel/boot/boot.asm @@ -14,7 +14,6 @@ .end: extern kernelMain -extern multibootInfo %define pageDirectory 0x500000 %define kernelPageTable 0x501000 @@ -24,8 +23,11 @@ %define mappedStackEnd 0xFFBFFFFF %define originalPageTable 0x503000 +ebxStart: db 0x00000000 + global _start _start: + mov [ebxStart], ebx mov esp, stackEnd lgdt [gdt32.end] mov ax, 16 @@ -35,7 +37,7 @@ mov fs, ax mov gs, ax jmp 0x08:.setupPaging -.setupPaging +.setupPaging: mov eax, pageDirectory mov ebx, originalPageTable mov ecx, 0 @@ -114,8 +116,10 @@ section .text higherKernelEntry: -.cleanOriginalEntryCode + mov ebx, [ebxStart] + push ebx +.cleanOriginalEntryCode: mov eax, 0xFF800000 mov dword [eax], 0 call kernelMain - jmp $ \ No newline at end of file + jmp $ diff --git a/src/kernel/include/memory.h b/src/kernel/include/memory.h index c5c47c0..1d40818 100644 --- a/src/kernel/include/memory.h +++ b/src/kernel/include/memory.h @@ -4,7 +4,8 @@ #include extern void setupMemory(); -extern void reservePagesUntil(uint32_t endPageId); -extern void memset(uint8_t *target, uint8_t byte, uint32_t size); +extern void reservePagesUntilPhysical(uint32_t endPageId); +extern void memset(void *target, uint8_t byte, uint32_t size); +extern void *kernelMapPhysical(void *address); #endif diff --git a/src/kernel/include/multiboot.h b/src/kernel/include/multiboot.h new file mode 100644 index 0000000..26c0f93 --- /dev/null +++ b/src/kernel/include/multiboot.h @@ -0,0 +1,48 @@ +#ifndef MULTIBOOT_H +#define MULTIBOOT_H + +#include + +// note: this structure supports more stuff, but I'm looking for the modules +// here. Look at +// https://android.googlesource.com/platform/external/grub/+/1650e5296608be8925d9831310c9ad3595fd6869/docs/multiboot.info +// for more info + +typedef enum { + BootCommandLineType = 1, + ModulesType = 3, + BasicMemoryInformationType = 4, + BiosBootDeviceType = 5, +} MultibootType; + +typedef struct { + uint32_t type; // multiboot type + uint32_t size; +} MultibootModuleInfo; + +typedef struct { + MultibootModuleInfo; + uint32_t memUpper; + uint32_t memLower; +} BasicMemoryInformation; + +typedef struct { + MultibootModuleInfo; + uint32_t biosDevice; + uint32_t partition; + uint32_t subPartition; +} BiosBootDevice; + +typedef struct { + MultibootModuleInfo; + char string[0]; +} BootCommandLine; + +typedef struct { + MultibootModuleInfo; + uint32_t moduleStart; + uint32_t moduleEnd; + char string[0]; +} Modules; + +#endif diff --git a/src/kernel/include/util.h b/src/kernel/include/util.h new file mode 100644 index 0000000..672e7dd --- /dev/null +++ b/src/kernel/include/util.h @@ -0,0 +1,7 @@ +#ifndef UTIL_H +#define UTIL_H + +#define U32(x) (uint32_t)(uintptr_t)(x) +#define PTR(x) (void *)(uintptr_t)(x) + +#endif diff --git a/src/kernel/main.c b/src/kernel/main.c index a7c59eb..3d19504 100644 --- a/src/kernel/main.c +++ b/src/kernel/main.c @@ -1,10 +1,11 @@ #include +#include #include -void *multibootInfo; // set by bootloader - -void kernelMain() { +void kernelMain(void *multibootInfo) { setupMemory(); + void *address = kernelMapPhysical(multibootInfo); + asm("mov %%eax, %0" ::"r"(address)); while (1) ; } diff --git a/src/kernel/memory/memory.c b/src/kernel/memory/memory.c index 6c4010a..0be4063 100644 --- a/src/kernel/memory/memory.c +++ b/src/kernel/memory/memory.c @@ -2,6 +2,6 @@ #include void setupMemory() { - reservePagesUntil(0x900); // address 0x900000, until the end of where the - // kernel data was mapped + reservePagesUntilPhysical(0x900); // address 0x900000, until the end of + // where the kernel data was mapped } diff --git a/src/kernel/memory/memset.c b/src/kernel/memory/memset.c index cbe1503..874cacc 100644 --- a/src/kernel/memory/memset.c +++ b/src/kernel/memory/memset.c @@ -1,6 +1,7 @@ #include -void memset(uint8_t *target, uint8_t byte, uint32_t size) { +void memset(void *_target, uint8_t byte, uint32_t size) { + uint8_t *target = _target; for (uint32_t i = 0; i < size; i++) { *target = byte; target++; diff --git a/src/kernel/memory/paging.c b/src/kernel/memory/paging.c index d68efa7..cf36e66 100644 --- a/src/kernel/memory/paging.c +++ b/src/kernel/memory/paging.c @@ -1,29 +1,112 @@ #include "paging.h" #include +#include -PageDirectoryEntry *kernelDirectory = (void *)0xFF800000; -PageTableEntry *kernelPageTable = (void *)0xFF801000; -PageTableEntry *kernelDataPageTable = (void *)0xFF802000; -uint32_t *isPageAllocated = (void *)0xFF803000; -uint32_t *isPageAllocatedCoarse = (void *)0xFF843000; -uint32_t pageSearchStart; +PageDirectoryEntry *kernelDirectory; +PageTableEntry *kernelCodePageTable, *kernelDataPageTable, *kernelUtilityPages; -void reservePage(uint32_t pageId); +PagingInfo *physicalPages, *kernelVirtualPages; -void reservePagesUntil(uint32_t endPageId) { - memset(isPageAllocated, 0, 0x40000); - memset(isPageAllocatedCoarse, 0, 0x10000); - for (uint32_t i = 0; i < endPageId; i++) { - reservePage(i); +void reservePage(PagingInfo *info, uint32_t pageId); + +void *kernelGetVirtualAddress(void *_address) { + uint32_t address = (uint32_t)(uintptr_t)_address; + if (address < 0x100000) { + return 0; } - pageSearchStart = endPageId; + if (address <= 0x500000) { + return _address + 0xFFC00000 - 0x100000; + } + if (address <= 0x900000) { + return _address + 0xFF800000 - 0x500000; + } + return 0; } -void reservePage(uint32_t pageId) { - uint32_t coarsePosition = pageId / 32; - isPageAllocated[coarsePosition] |= 1 << (pageId % 32); - if (isPageAllocated[coarsePosition] == ~0) { - isPageAllocatedCoarse[coarsePosition / 32] |= 1 - << (coarsePosition % 32); +void *getPhysicalAddress(void *address, PageDirectoryEntry *pageDirectory) { + VirtualAddress *virtual = (void *)&address; + uint32_t pageTableLocation = + pageDirectory[virtual->pageDirectoryIndex].pageTableID; + PageTableEntry *pageTable = PTR(pageTableLocation << 12); + pageTable = kernelGetVirtualAddress(pageTable); + uint32_t pageBase = pageTable[virtual->pageTableIndex].targetAddress; + return PTR(pageBase << 12 | virtual->pageOffset); +} + +void mapDirectoryEntry(PageDirectoryEntry *directory, uint32_t pageTableIndex, + PageTableEntry *pageTable, PagingInfo *pagingInfo) { + directory[pageTableIndex].pageTableID = + U32(getPhysicalAddress(pageTable, directory)) >> 12; + directory[pageTableIndex].writable = 1; + directory[pageTableIndex].present = 1; + pagingInfo->isPageTableInUse[pageTableIndex / 32] |= + 1 << (pageTableIndex % 32); +} + +void reservePagesUntilPhysical(uint32_t endPageId) { + void *buffer = (void *)0xFF800000; + kernelDirectory = buffer; + memset(kernelDirectory, 0, 0xFF8); + buffer += 0x1000; + kernelCodePageTable = buffer; + buffer += 0x1000; + kernelDataPageTable = buffer; + buffer += 0x1000; + kernelUtilityPages = buffer; + buffer += 0x1000; + physicalPages = buffer; + buffer += sizeof(PagingInfo); + kernelVirtualPages = buffer; + buffer += sizeof(PagingInfo); + memset(physicalPages, 0, 2 * sizeof(PagingInfo)); + for (uint32_t i = 0; i < endPageId; i++) { + reservePage(physicalPages, i); } + for (uint32_t i = 0; i < 0x800; i++) { + reservePage(kernelVirtualPages, i + 0xFF800); + } + memset(kernelUtilityPages, 0, 0x1000); + mapDirectoryEntry(kernelDirectory, 0, kernelUtilityPages, + kernelVirtualPages); + physicalPages->pageSearchStart = endPageId; +} + +void reservePage(PagingInfo *info, uint32_t pageId) { + uint32_t coarsePosition = pageId / 32; + info->isPageAllocated[coarsePosition] |= 1 << (pageId % 32); + if (info->isPageAllocated[coarsePosition] == ~0) { + info->isPageAllocatedCoarse[coarsePosition / 32] |= + 1 << (coarsePosition % 32); + } +} + +uint32_t findPage(PagingInfo *info) { + for (uint32_t veryCoarse = info->pageSearchStart / 1024;; veryCoarse++) { + if (info->isPageAllocatedCoarse[veryCoarse] == ~0) { + continue; + } + for (uint8_t coarse = 0; coarse < 32; coarse++) { + if (info->isPageAllocatedCoarse[veryCoarse] & (1 << coarse)) { + continue; + } + uint32_t coarsePageId = (veryCoarse * 32 + coarse); + for (uint8_t fine = 0; fine < 32; fine++) { + if (info->isPageAllocated[coarsePageId] & (1 << fine)) { + continue; + } + return coarsePageId * 32 + fine; + } + } + } +} + +void *kernelMapPhysical(void *address) { + uint32_t physicalPage = U32(address) >> 12; + reservePage(physicalPages, physicalPage); + uint32_t virtualPage = findPage(kernelVirtualPages); + reservePage(kernelVirtualPages, virtualPage); + kernelUtilityPages[virtualPage].targetAddress = physicalPage; + kernelUtilityPages[virtualPage].writable = 1; + kernelUtilityPages[virtualPage].present = 1; + return PTR((virtualPage << 12) + (U32(address) & 0xFFF)); } diff --git a/src/kernel/memory/paging.h b/src/kernel/memory/paging.h index 70dc0d0..208f670 100644 --- a/src/kernel/memory/paging.h +++ b/src/kernel/memory/paging.h @@ -12,8 +12,8 @@ uint32_t dirty : 1; uint32_t reserved2 : 2; uint32_t available : 3; - uint32_t pageTableID : 22; -} PageDirectoryEntry; + uint32_t pageTableID : 20; +} __attribute__((packed)) PageDirectoryEntry; typedef struct { uint32_t present : 1; @@ -27,6 +27,19 @@ uint32_t global : 1; uint32_t available : 3; uint32_t targetAddress : 20; -} PageTableEntry; +} __attribute__((packed)) PageTableEntry; + +typedef struct { + uint32_t isPageAllocated[0x8000]; + uint32_t isPageAllocatedCoarse[0x400]; + uint32_t isPageTableInUse[0x20]; + uint32_t pageSearchStart; +} PagingInfo; + +typedef struct { + uint32_t pageOffset : 12; + uint32_t pageTableIndex : 10; + uint32_t pageDirectoryIndex : 10; +} __attribute__((packed)) VirtualAddress; #endif diff --git a/src/userland/loader/Makefile b/src/userland/loader/Makefile new file mode 100644 index 0000000..d6c7c6c --- /dev/null +++ b/src/userland/loader/Makefile @@ -0,0 +1,29 @@ +CC = i686-elf-gcc +CCFLAGS = -m32 -mtune=generic -ffreestanding -nostdlib -c -I ../../include -I include -Wno-discarded-qualifiers -fms-extensions -Wno-shift-count-overflow -O0 +LD = i686-elf-ld +LD_FLAGS = -z max-page-size=0x1000 +AS = nasm +ASFlAGS = -felf32 + +BUILD_FOLDER = build + +SOURCE_FILES := $(shell find . -name *.c -or -name *.asm -or -name *.s) +OBJS := $(SOURCE_FILES:%=$(BUILD_FOLDER)/%.o) + +../../../initrd/loader: $(OBJS) + @echo "linking user program loader" + @$(LD) $(LD_FLAGS) -o ../../../initrd/loader $(OBJS) + +$(BUILD_FOLDER)/%.asm.o: %.asm + @echo "asembling $<" + @mkdir -p $(dir $@) + @$(AS) $(ASFlAGS) $< -o $@ + +$(BUILD_FOLDER)/%.c.o: %.c + @echo "compiling $<" + @mkdir -p $(dir $@) + @$(CC) $(CCFLAGS) -r $< -o $@ + +clean: + @echo "clearing build folder" + @rm -r $(BUILD_FOLDER) diff --git a/src/userland/loader/main.c b/src/userland/loader/main.c new file mode 100644 index 0000000..bee09ed --- /dev/null +++ b/src/userland/loader/main.c @@ -0,0 +1,31 @@ +#include + +uint8_t inb(uint16_t port) { + uint8_t result; + __asm__("in %%dx, %%al" : "=a"(result) : "d"(port)); + return result; +} + +void outb(uint16_t port, uint8_t val) { + asm volatile("outb %0, %1" : : "a"(val), "Nd"(port)); +} + +void Parallel_SendByte(unsigned char pData) { + unsigned char lControl; + + while (!(inb(0x379) & 0x80)) { + } + outb(0x378, pData); + + lControl = inb(0x37A); + outb(0x37A, lControl | 1); + outb(0x37A, lControl); + while (!(inb(0x379) & 0x80)) { + } +} + +int32_t main() { + // send a x to the parralel port to test stuff out + Parallel_SendByte('x'); + return 0; +}