diff --git a/.gitignore b/.gitignore index 42f9498..8e35884 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,11 @@ test-*.c *.yml CNAME +# Other stuff +multiboot.pdf +grub.log +Makefile.out.2 +build/bin/s** # Linker output *.ilk diff --git a/Makefile b/Makefile index 79e3b32..d58bb68 100644 --- a/Makefile +++ b/Makefile @@ -40,24 +40,51 @@ tests: make tests -f build/Makefile.out.2 rm build/Makefile.out build/Makefile.out.2 +#Programs ASM=nasm ASMFLAGS= BOOTFLAGS=-f bin -MBRDIR=boot/mbr +#Folders +MBRDIR=boot/grub LOADERDIR=boot/loader OBJDIR=build/obj BINDIR=build/bin -boot.mbr.asm: $(MBRDIR)/mbr.asm $(MBRDIR)/mbr.inc - $(ASM) $(BOOTFLAGS) $(MBRDIR)/mbr.asm -o $(OBJDIR)/boot/mbr.bin +#Color codes +CL='\033[0;32m' +CL2='\033[1;31m' +CL3='\033[0m' +NC='\033[1;37m' + +boot.mbr: $(BINDIR)/disk.img $(MBRDIR)/grub.cfg + @mkdir -p $(BINDIR)/disk + @echo ${CL2}[boot.mbr]${NC} Installing bootloader on image...${CL3} + @$(MBRDIR)/grub-install.sh $(BINDIR)/disk.img $(BINDIR)/disk $(MBRDIR)/grub.cfg + @echo ${CL2}[boot.mbr]${CL} OK${CL3} + @rmdir $(BINDIR)/disk boot.loader.asm: $(LOADERDIR)/loader.asm - $(ASM) $(BOOTFLAGS) $(LOADERDIR)/loader.asm -o $(OBJDIR)/boot/loader.bin + @echo ${CL2}[boot.loader.asm]${NC} Making loader.bin...${CL3} + @$(ASM) $(BOOTFLAGS) $(LOADERDIR)/loader.asm -o $(OBJDIR)/boot/loader.bin > /dev/null + @echo ${CL2}[boot.loader.asm]${CL} OK${CL3} -bootloader: boot.mbr.asm boot.loader.asm - cp $(OBJDIR)/boot/mbr.bin $(BINDIR)/mbr.bin - cp $(OBJDIR)/boot/loader.bin $(BINDIR)/loader.bin +bootloader: boot.mbr boot.loader.asm + @mkdir -p $(BINDIR)/disk + @echo ${CL2}[bootloader]${NC} Constructing bootloader...${CL3} + @$(MBRDIR)/mount.sh $(BINDIR)/disk.img $(BINDIR)/disk + @cp $(OBJDIR)/boot/loader.bin $(BINDIR)/disk/boot/loader.bin + @$(MBRDIR)/umount.sh $(BINDIR)/disk + @echo ${CL2}[bootloader]${CL} OK${CL3} + @rmdir $(BINDIR)/disk -all: bootloader kernel +make_disk: + @echo ${CL2}[make_disk]${NC} Constructing disk image...${CL3} + @$(MBRDIR)/create_disk.sh $(BINDIR)/disk.img + @echo ${CL2}[make_disk]${CL} OK${CL3} +boot: make_disk bootloader + @echo ${CL2}[[boot]]${CL} Terminated without error.${CL3} + +all: boot kernel + @echo ${CL2}[[all]]${CL} Terminated without error.${CL3} diff --git a/Readme.md b/Readme.md index 251d36e..9e99c25 100644 --- a/Readme.md +++ b/Readme.md @@ -5,7 +5,9 @@ ### Fully free operating system from scratch (WIP) -#### Master Branch +#### Loader Branch + +Development focused on the kernel loader. For the project plan, see [OS/K Project](https://github.com/orgs/os-k-team/projects/1) diff --git a/boot/folder.desc b/boot/folder.desc index fc76abf..3eb3f85 100644 --- a/boot/folder.desc +++ b/boot/folder.desc @@ -27,12 +27,13 @@ This folder contains the source for OS/K's bootloader. OS/K being intended to only run on x86-64 systems, we have not divided this folder into one sub-folder per architecture. -It is divided in two parts each of exactly 512 bytes: - - mbr.s (and its auxiliary file mbr.inc) - This is our Master Boot Record (MBR). It switches to long mode - (64 bits mode) then loads the second half of the bootloader. - The MBR must be placed precisely on the first sector of the hard drive. +The bootloader itself is external to the OS/K project. We are using GRUB 2 to load +our kernel loader in memory. - - loader.s - This is the Kernel Loader. It switches to long mode and makes stuff. +The kernel loader, that we call the loader, is the main subject of this folder. +This loader is intended to load the ELF64 kernel at the specified address and +prepare it for the hard work it have to do : + - Parsing the ELF64 + - Load the kernel + - Prepare a structure for it with memory map, cpu infos, and other devices infos. diff --git a/boot/grub/create_disk.sh b/boot/grub/create_disk.sh new file mode 100755 index 0000000..ba6e227 --- /dev/null +++ b/boot/grub/create_disk.sh @@ -0,0 +1,66 @@ +#=----------------------------------------------------------------------------=# +# GNU GPL OS/K # +# # +# Desc: OS/K image maker script # +# # +# # +# Copyright © 2018-2019 The OS/K Team # +# # +# This file is part of OS/K. # +# # +# OS/K is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# any later version. # +# # +# OS/K is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY# without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with OS/K. If not, see . # +#=----------------------------------------------------------------------------=# + +#Color codes +CL='\033[0;32m' +CL2='\033[1;36m' +CL3='\033[0m' +NC='\033[1;37m' + +set -e #exit if error + +## Create the image +echo ${CL2}[create_disk.sh]${NC} Creating image... \(dd\)${CL3} +dd if=/dev/zero of=$1 bs=512 count=131072 > /dev/null + +echo ${CL2}[create_disk.sh]${NC} Partitionning image... \(fdisk\)${CL3} +## Partition the image +# WARNING, DO NOT DELETE SPACES ! +sudo fdisk $1 > /dev/null < /dev/null +sudo losetup /dev/loop0 $1 -o 1048576 > /dev/null #mounting the logical partition + +echo ${CL2}[create_disk.sh]${NC} Formatting image... \(mkdosfs\)${CL3} +## Format +sudo mkdosfs -F32 -f 2 /dev/loop0 > /dev/null + +echo ${CL2}[create_disk.sh]${NC} Sync image... \(sync\)${CL3} +sync + +echo ${CL2}[create_disk.sh]${NC} Unmounting... \(losetup\)${CL3} +sudo losetup -D > /dev/null + +echo ${CL2}[create_disk.sh]${CL} Terminated without error.${CL3} diff --git a/boot/grub/grub-install.sh b/boot/grub/grub-install.sh new file mode 100755 index 0000000..44d591f --- /dev/null +++ b/boot/grub/grub-install.sh @@ -0,0 +1,60 @@ +#=----------------------------------------------------------------------------=# +# GNU GPL OS/K # +# # +# Desc: Grub installation script for the OS/K image # +# # +# # +# Copyright © 2018-2019 The OS/K Team # +# # +# This file is part of OS/K. # +# # +# OS/K is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# any later version. # +# # +# OS/K is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY# without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with OS/K. If not, see . # +#=----------------------------------------------------------------------------=# + +#Color codes +CL='\033[0;32m' +CL2='\033[1;36m' +CL3='\033[0m' +NC='\033[1;37m' + +set -e #exit if error + +echo ${CL2}[grub-install.sh]${NC} Mouting image... \(losetup\)${CL3} +## Prepare Mount +sudo losetup -D > /dev/null +sudo losetup /dev/loop0 $1 > /dev/null # mounting the device block +sudo losetup /dev/loop1 $1 -o 1048576 > /dev/null #mounting the logical partition + +echo ${CL2}[grub-install.sh]${NC} Mounting volume... \(mount\)${CL3} +## Mount +sudo mount /dev/loop1 $2 > /dev/null + +echo ${CL2}[grub-install.sh]${NC} Installing grub... \(grub-install\)${CL3} +## Install grub +sudo grub-install -V +sudo grub-install --target=i386-pc --debug --root-directory=$2 --boot-directory=$2/boot --no-floppy --modules="part_msdos biosdisk fat multiboot configfile" /dev/loop0 2> grub.log + +echo ${CL2}[grub-install.sh]${NC} Copying grub.cfg +sudo cp $3 $2/boot/grub/grub.cfg > /dev/null + +echo ${CL2}[grub-install.sh]${NC} Sync image... \(sync\)${CL3} +sync + +echo ${CL2}[grub-install.sh]${NC} Unmounting volume... \(umount\)${CL3} +sudo umount /dev/loop1 > /dev/null + +echo ${CL2}[grub-install.sh]${NC} Unmounting image... \(losetup\)${CL3} +sudo losetup -D > /dev/null + +echo ${CL2}[grub-install.sh]${CL} Terminated without error. See grub.log for more informations.${CL3} diff --git a/boot/grub/grub.cfg b/boot/grub/grub.cfg new file mode 100755 index 0000000..878c1b8 --- /dev/null +++ b/boot/grub/grub.cfg @@ -0,0 +1,32 @@ +#=----------------------------------------------------------------------------=# +# GNU GPL OS/K # +# # +# Desc: Grub 2 configuration file for OS/K boot # +# # +# # +# Copyright © 2018-2019 The OS/K Team # +# # +# This file is part of OS/K. # +# # +# OS/K is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# any later version. # +# # +# OS/K is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY# without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with OS/K. If not, see . # +#=----------------------------------------------------------------------------=# + +set timeout=5 + +set default=0 #Set the default menu entry + +menuentry "OS/K (pre-pre-alpha 0.0.1)" { + multiboot /boot/loader.bin # The multiboot command replaces the kernel command + boot +} diff --git a/boot/grub/include/multiboot.h b/boot/grub/include/multiboot.h new file mode 100644 index 0000000..b181607 --- /dev/null +++ b/boot/grub/include/multiboot.h @@ -0,0 +1,417 @@ +/* multiboot2.h - Multiboot 2 header file. */ +/* Copyright (C) 1999,2003,2007,2008,2009,2010 Free Software Foundation, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ANY + * DEVELOPER OR DISTRIBUTOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR + * IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef MULTIBOOT_HEADER +#define MULTIBOOT_HEADER 1 + +/* How many bytes from the start of the file we search for the header. */ +#define MULTIBOOT_SEARCH 32768 +#define MULTIBOOT_HEADER_ALIGN 8 + +/* The magic field should contain this. */ +#define MULTIBOOT2_HEADER_MAGIC 0xe85250d6 + +/* This should be in %eax. */ +#define MULTIBOOT2_BOOTLOADER_MAGIC 0x36d76289 + +/* Alignment of multiboot modules. */ +#define MULTIBOOT_MOD_ALIGN 0x00001000 + +/* Alignment of the multiboot info structure. */ +#define MULTIBOOT_INFO_ALIGN 0x00000008 + +/* Flags set in the 'flags' member of the multiboot header. */ + +#define MULTIBOOT_TAG_ALIGN 8 +#define MULTIBOOT_TAG_TYPE_END 0 +#define MULTIBOOT_TAG_TYPE_CMDLINE 1 +#define MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME 2 +#define MULTIBOOT_TAG_TYPE_MODULE 3 +#define MULTIBOOT_TAG_TYPE_BASIC_MEMINFO 4 +#define MULTIBOOT_TAG_TYPE_BOOTDEV 5 +#define MULTIBOOT_TAG_TYPE_MMAP 6 +#define MULTIBOOT_TAG_TYPE_VBE 7 +#define MULTIBOOT_TAG_TYPE_FRAMEBUFFER 8 +#define MULTIBOOT_TAG_TYPE_ELF_SECTIONS 9 +#define MULTIBOOT_TAG_TYPE_APM 10 +#define MULTIBOOT_TAG_TYPE_EFI32 11 +#define MULTIBOOT_TAG_TYPE_EFI64 12 +#define MULTIBOOT_TAG_TYPE_SMBIOS 13 +#define MULTIBOOT_TAG_TYPE_ACPI_OLD 14 +#define MULTIBOOT_TAG_TYPE_ACPI_NEW 15 +#define MULTIBOOT_TAG_TYPE_NETWORK 16 +#define MULTIBOOT_TAG_TYPE_EFI_MMAP 17 +#define MULTIBOOT_TAG_TYPE_EFI_BS 18 +#define MULTIBOOT_TAG_TYPE_EFI32_IH 19 +#define MULTIBOOT_TAG_TYPE_EFI64_IH 20 +#define MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR 21 + +#define MULTIBOOT_HEADER_TAG_END 0 +#define MULTIBOOT_HEADER_TAG_INFORMATION_REQUEST 1 +#define MULTIBOOT_HEADER_TAG_ADDRESS 2 +#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS 3 +#define MULTIBOOT_HEADER_TAG_CONSOLE_FLAGS 4 +#define MULTIBOOT_HEADER_TAG_FRAMEBUFFER 5 +#define MULTIBOOT_HEADER_TAG_MODULE_ALIGN 6 +#define MULTIBOOT_HEADER_TAG_EFI_BS 7 +#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI32 8 +#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI64 9 +#define MULTIBOOT_HEADER_TAG_RELOCATABLE 10 + +#define MULTIBOOT_ARCHITECTURE_I386 0 +#define MULTIBOOT_ARCHITECTURE_MIPS32 4 +#define MULTIBOOT_HEADER_TAG_OPTIONAL 1 + +#define MULTIBOOT_LOAD_PREFERENCE_NONE 0 +#define MULTIBOOT_LOAD_PREFERENCE_LOW 1 +#define MULTIBOOT_LOAD_PREFERENCE_HIGH 2 + +#define MULTIBOOT_CONSOLE_FLAGS_CONSOLE_REQUIRED 1 +#define MULTIBOOT_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED 2 + +#ifndef ASM_FILE + +typedef unsigned char multiboot_uint8_t; +typedef unsigned short multiboot_uint16_t; +typedef unsigned int multiboot_uint32_t; +typedef unsigned long long multiboot_uint64_t; + +struct multiboot_header +{ + /* Must be MULTIBOOT_MAGIC - see above. */ + multiboot_uint32_t magic; + + /* ISA */ + multiboot_uint32_t architecture; + + /* Total header length. */ + multiboot_uint32_t header_length; + + /* The above fields plus this one must equal 0 mod 2^32. */ + multiboot_uint32_t checksum; +}; + +struct multiboot_header_tag +{ + multiboot_uint16_t type; + multiboot_uint16_t flags; + multiboot_uint32_t size; +}; + +struct multiboot_header_tag_information_request +{ + multiboot_uint16_t type; + multiboot_uint16_t flags; + multiboot_uint32_t size; + multiboot_uint32_t requests[0]; +}; + +struct multiboot_header_tag_address +{ + multiboot_uint16_t type; + multiboot_uint16_t flags; + multiboot_uint32_t size; + multiboot_uint32_t header_addr; + multiboot_uint32_t load_addr; + multiboot_uint32_t load_end_addr; + multiboot_uint32_t bss_end_addr; +}; + +struct multiboot_header_tag_entry_address +{ + multiboot_uint16_t type; + multiboot_uint16_t flags; + multiboot_uint32_t size; + multiboot_uint32_t entry_addr; +}; + +struct multiboot_header_tag_console_flags +{ + multiboot_uint16_t type; + multiboot_uint16_t flags; + multiboot_uint32_t size; + multiboot_uint32_t console_flags; +}; + +struct multiboot_header_tag_framebuffer +{ + multiboot_uint16_t type; + multiboot_uint16_t flags; + multiboot_uint32_t size; + multiboot_uint32_t width; + multiboot_uint32_t height; + multiboot_uint32_t depth; +}; + +struct multiboot_header_tag_module_align +{ + multiboot_uint16_t type; + multiboot_uint16_t flags; + multiboot_uint32_t size; +}; + +struct multiboot_header_tag_relocatable +{ + multiboot_uint16_t type; + multiboot_uint16_t flags; + multiboot_uint32_t size; + multiboot_uint32_t min_addr; + multiboot_uint32_t max_addr; + multiboot_uint32_t align; + multiboot_uint32_t preference; +}; + +struct multiboot_color +{ + multiboot_uint8_t red; + multiboot_uint8_t green; + multiboot_uint8_t blue; +}; + +struct multiboot_mmap_entry +{ + multiboot_uint64_t addr; + multiboot_uint64_t len; +#define MULTIBOOT_MEMORY_AVAILABLE 1 +#define MULTIBOOT_MEMORY_RESERVED 2 +#define MULTIBOOT_MEMORY_ACPI_RECLAIMABLE 3 +#define MULTIBOOT_MEMORY_NVS 4 +#define MULTIBOOT_MEMORY_BADRAM 5 + multiboot_uint32_t type; + multiboot_uint32_t zero; +}; +typedef struct multiboot_mmap_entry multiboot_memory_map_t; + +struct multiboot_tag +{ + multiboot_uint32_t type; + multiboot_uint32_t size; +}; + +struct multiboot_tag_string +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + char string[0]; +}; + +struct multiboot_tag_module +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t mod_start; + multiboot_uint32_t mod_end; + char cmdline[0]; +}; + +struct multiboot_tag_basic_meminfo +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t mem_lower; + multiboot_uint32_t mem_upper; +}; + +struct multiboot_tag_bootdev +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t biosdev; + multiboot_uint32_t slice; + multiboot_uint32_t part; +}; + +struct multiboot_tag_mmap +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t entry_size; + multiboot_uint32_t entry_version; + struct multiboot_mmap_entry entries[0]; +}; + +struct multiboot_vbe_info_block +{ + multiboot_uint8_t external_specification[512]; +}; + +struct multiboot_vbe_mode_info_block +{ + multiboot_uint8_t external_specification[256]; +}; + +struct multiboot_tag_vbe +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + + multiboot_uint16_t vbe_mode; + multiboot_uint16_t vbe_interface_seg; + multiboot_uint16_t vbe_interface_off; + multiboot_uint16_t vbe_interface_len; + + struct multiboot_vbe_info_block vbe_control_info; + struct multiboot_vbe_mode_info_block vbe_mode_info; +}; + +struct multiboot_tag_framebuffer_common +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + + multiboot_uint64_t framebuffer_addr; + multiboot_uint32_t framebuffer_pitch; + multiboot_uint32_t framebuffer_width; + multiboot_uint32_t framebuffer_height; + multiboot_uint8_t framebuffer_bpp; +#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0 +#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1 +#define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT 2 + multiboot_uint8_t framebuffer_type; + multiboot_uint16_t reserved; +}; + +struct multiboot_tag_framebuffer +{ + struct multiboot_tag_framebuffer_common common; + + union + { + struct + { + multiboot_uint16_t framebuffer_palette_num_colors; + struct multiboot_color framebuffer_palette[0]; + }; + struct + { + multiboot_uint8_t framebuffer_red_field_position; + multiboot_uint8_t framebuffer_red_mask_size; + multiboot_uint8_t framebuffer_green_field_position; + multiboot_uint8_t framebuffer_green_mask_size; + multiboot_uint8_t framebuffer_blue_field_position; + multiboot_uint8_t framebuffer_blue_mask_size; + }; + }; +}; + +struct multiboot_tag_elf_sections +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t num; + multiboot_uint32_t entsize; + multiboot_uint32_t shndx; + char sections[0]; +}; + +struct multiboot_tag_apm +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint16_t version; + multiboot_uint16_t cseg; + multiboot_uint32_t offset; + multiboot_uint16_t cseg_16; + multiboot_uint16_t dseg; + multiboot_uint16_t flags; + multiboot_uint16_t cseg_len; + multiboot_uint16_t cseg_16_len; + multiboot_uint16_t dseg_len; +}; + +struct multiboot_tag_efi32 +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t pointer; +}; + +struct multiboot_tag_efi64 +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint64_t pointer; +}; + +struct multiboot_tag_smbios +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint8_t major; + multiboot_uint8_t minor; + multiboot_uint8_t reserved[6]; + multiboot_uint8_t tables[0]; +}; + +struct multiboot_tag_old_acpi +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint8_t rsdp[0]; +}; + +struct multiboot_tag_new_acpi +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint8_t rsdp[0]; +}; + +struct multiboot_tag_network +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint8_t dhcpack[0]; +}; + +struct multiboot_tag_efi_mmap +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t descr_size; + multiboot_uint32_t descr_vers; + multiboot_uint8_t efi_mmap[0]; +}; + +struct multiboot_tag_efi32_ih +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t pointer; +}; + +struct multiboot_tag_efi64_ih +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint64_t pointer; +}; + +struct multiboot_tag_load_base_addr +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t load_base_addr; +}; + +#endif /* ! ASM_FILE */ + +#endif /* ! MULTIBOOT_HEADER */ diff --git a/boot/grub/mount.sh b/boot/grub/mount.sh new file mode 100755 index 0000000..a880f03 --- /dev/null +++ b/boot/grub/mount.sh @@ -0,0 +1,38 @@ +#=----------------------------------------------------------------------------=# +# GNU GPL OS/K # +# # +# Desc: Simple OS/K image mount script # +# # +# # +# Copyright © 2018-2019 The OS/K Team # +# # +# This file is part of OS/K. # +# # +# OS/K is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# any later version. # +# # +# OS/K is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY# without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with OS/K. If not, see . # +#=----------------------------------------------------------------------------=# + +#Color codes +CL='\033[0;32m' +CL2='\033[1;36m' +CL3='\033[0m' +NC='\033[1;37m' + +set -e #exit if error + +echo ${CL2}[mount.sh]${NC} Mouting image... \(losetup\)${CL3} +sudo losetup -D > /dev/null +sudo losetup /dev/loop0 $1 -o 1048576 /dev/null #mounting the logical partition +echo ${CL2}[mount.sh]${NC} Mouting volume... \(mount\)${CL3} +sudo mount -t vfat /dev/loop0 $2 -o rw,uid=$(id -u),gid=$(id -g) > /dev/null +echo ${CL2}[mount.sh]${CL} Terminated without error.${CL3} diff --git a/boot/grub/multiboot.pdf b/boot/grub/multiboot.pdf new file mode 100644 index 0000000..e32056f Binary files /dev/null and b/boot/grub/multiboot.pdf differ diff --git a/boot/grub/umount.sh b/boot/grub/umount.sh new file mode 100755 index 0000000..78bfa66 --- /dev/null +++ b/boot/grub/umount.sh @@ -0,0 +1,37 @@ +#=----------------------------------------------------------------------------=# +# GNU GPL OS/K # +# # +# Desc: Simple unmount script # +# # +# # +# Copyright © 2018-2019 The OS/K Team # +# # +# This file is part of OS/K. # +# # +# OS/K is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# any later version. # +# # +# OS/K is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY# without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with OS/K. If not, see . # +#=----------------------------------------------------------------------------=# + +#Color codes +CL='\033[0;32m' +CL2='\033[1;36m' +CL3='\033[0m' +NC='\033[1;37m' + +set -e #exit if error +sleep 3 +echo ${CL2}[umount.sh]${NC} Unmounting volume... \(umount\)${CL3} +sudo umount $1 +echo ${CL2}[umount.sh]${NC} Unmounting image... \(losetup\)${CL3} +sudo losetup -D +echo ${CL2}[umount.sh]${CL} Terminated without error.${CL3} diff --git a/boot/loader/loader.asm b/boot/loader/loader.asm index 6734aec..807ed10 100644 --- a/boot/loader/loader.asm +++ b/boot/loader/loader.asm @@ -25,16 +25,41 @@ %define DEBUG -[BITS 16] -[ORG 0x1000] +[BITS 32] +[global _start] +[ORG 0x100000] ; Where GRUB loads us. -mov ax, cs ; correcting cs after the horrible far jump -mov ds, ax ; hm... And ds too -mov es, ax ; And es because it is jealous +%include "boot/loader/multiboot.inc" -mov [Bootdrv], dl -xor dl, dl -jmp 0x0000:main +_start: + mov ax, cs ; correcting cs after the horrible far jump + mov ds, ax ; hm... And ds too + mov es, ax ; And es because it is jealous + + mov [Bootdrv], dl + xor dl, dl + jmp 0x0000:main ; pas sûr +multiboot_header: + + align 4 + dd MB_HEADER_MAGIC + dd MB_HEADER_FLAGS + dd CHECKSUM + dd multiboot_header ; Header address + dd _start ; Address of code entry point + dd 00 ; (end of code) not necessary + dd 00 ; (bss) not necessary + dd MB_start ; entry address GRUB will start at + +MB_start: + mov esp, KERNEL_STACK ; Setup the stack + push 0 ; Reset EFLAGS + popf + push eax ; 2nd argument is magic number + push ebx ; 1st argument multiboot info pointer + call main + add esp, 8 ; Cleanup 8 bytes pushed as arguments + jmp Die %include "boot/loader/cpu/cpuid.asm" %include "boot/loader/io/rmterm.asm" @@ -42,37 +67,6 @@ jmp 0x0000:main main: - ;; compatibility check - push si - mov si, Init - call PrintB - pop si - - call Is64bits - - jc ErrorNo64 - push si - mov si, Pass - call PrintB - pop si - - ;; Enabling A20 - push si - mov si, EnA20 - call PrintB - pop si - - call set_a20 - - push si - mov si, Pass - call PrintB - pop si - - ;; DISABLING CURSOR BLINKING AND GETTING INFOS - call get_dimensions - call disable_cursor - ;;GO GDT64 cli ; disable interrupts lgdt [GDT64] @@ -92,10 +86,6 @@ main: push dword [VGA_HEIGHT] jmp (CODE_SELECTOR-GDT64):main32 -;; THE HOLE ----------------------------------------------------------------- ;; -ErrorNo64: - mov si, NoLongMode - call PrintB Die: cli hlt ; die nooooow diff --git a/boot/loader/multiboot.inc b/boot/loader/multiboot.inc new file mode 100644 index 0000000..f013eda --- /dev/null +++ b/boot/loader/multiboot.inc @@ -0,0 +1,33 @@ +;=----------------------------------------------------------------------------=; +; GNU GPL OS/K ; +; ; +; Desc: Multiboot header ; +; (x86_64 architecture only) ; +; ; +; ; +; Copyright © 2018-2019 The OS/K Team ; +; ; +; This file is part of OS/K. ; +; ; +; OS/K is free software: you can redistribute it and/or modify ; +; it under the terms of the GNU General Public License as published by ; +; the Free Software Foundation, either version 3 of the License, or ; +; (at your option) any later version. ; +; ; +; OS/K is distributed in the hope that it will be useful, ; +; but WITHOUT ANY WARRANTY; without even the implied warranty of ; +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; +; GNU General Public License for more details. ; +; ; +; You should have received a copy of the GNU General Public License ; +; along with OS/K. If not, see . ; +;=----------------------------------------------------------------------------=; + +;; MULTIBOOT HEADER +%define MB_AOUT_KLUDGE 1 << 16 ; We are not an ELF executable +%define MB_ALIGN 1 << 0 ; Ask to align loaded modules on page boundaries +%define MB_MEMINFO 1 << 1 ; Ask to provide memory map +%define MB_HEADER_MAGIC 0x1BADB002 +%define MB_HEADER_FLAGS MB_AOUT_KLUDGE|MB_ALIGN|MB_MEMINFO +%define CHECKSUM -(MB_HEADER_MAGIC + MB_HEADER_FLAGS) +%define KERNEL_STACK 0x00200000 ; Stack starts at the 2mb address & grows down diff --git a/boot/mbr/mbr.asm b/boot/mbr/mbr.asm deleted file mode 100644 index 1a08f74..0000000 --- a/boot/mbr/mbr.asm +++ /dev/null @@ -1,191 +0,0 @@ -;=----------------------------------------------------------------------------=; -; GNU GPL OS/K ; -; ; -; Desc: Bootsector for OS/K ; -; (x86_64 architecture only) ; -; ; -; ; -; Copyright © 2018-2019 The OS/K Team ; -; ; -; This file is part of OS/K. ; -; ; -; OS/K is free software: you can redistribute it and/or modify ; -; it under the terms of the GNU General Public License as published by ; -; the Free Software Foundation, either version 3 of the License, or ; -; any later version. ; -; ; -; OS/K is distributed in the hope that it will be useful, ; -; but WITHOUT ANY WARRANTY; without even the implied warranty of ; -; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; -; GNU General Public License for more details. ; -; ; -; You should have received a copy of the GNU General Public License ; -; along with OS/K. If not, see . ; -;=----------------------------------------------------------------------------=; - -;; BOOT "SEGMENT" -%define BOOT_SEG 0x07c0 ; (BOOT_SEG << 4) + BOOT_OFF = 0x007c00 -%define BOOT_OFF 0x0000 - -;; STACK "SEGMENT" -%define STACK_SEG 0x0600 ; (STACK_SEG << 4) + STACK_OFF = 0x007000 -%define STACK_OFF 0x1000 - -;; DISK BUFFER "SEGMENT" -%define BUFFER_SEG 0x2000 ; (BUFFER_SEG << 4) + BUFFER_OFF = 0x020000 -%define BUFFER_OFF 0x0000 - -;; SECOND STAGE LOADER "SEGMENT" -%define LOAD_SEG 0x0000 ; (LOAD_SEG << 4) + LOAD_OFF = 0x001000 -%define LOAD_OFF 0x1000 - -[BITS 16] ; Ensure 16-bit code (because fuck UEFI) - -Intro: - - jmp short _start ; Jump over the BIOS PARAMETER BLOCK - nop ; Required by BIOS to recognize the Disk loul -BPB: - ;---------------------------------------------------; - ; Disk description table ; - ;---------------------------------------------------; - %define OEMName bp+0x03 ; Disk label - %define bytesPerSector bp+0x0b ; Bytes per sector - %define sectorsPerCluster bp+0x0d ; Sectors per cluster - %define reservedSectors bp+0x0e ; Reserved sectors - %define fats bp+0x10 ; Number of fats - %define rootDirEntries bp+0x11 ; Number of entries in root dir - %define sectors bp+0x13 ; Logical sectors - %define mediaType bp+0x15 ; Media descriptor byte - %define fatSectors bp+0x16 ; Sectors per FAT - %define sectorsPerTrack bp+0x18 ; Sectors per track - %define heads bp+0x1a ; Number of sides/heads - %define hiddenSectors bp+0x1c ; Hidden sectors - %define hugeSectors bp+0x20 ; LBA sectors - %define biosBootdrvNum bp+0x24 ; Bootdrv number - %define reserved bp+0x25 ; This is not used - %define bootSignature bp+0x26 ; Bootdrv signature - %define volumeId bp+0x27 ; Volume ID - %define volumeLabel bp+0x2b ; Volume Label - %define fatTypeLabel bp+0x36 ; File system type - - times 0x3b db 0x00 ; ALLOCATE THE SECTORS FOR THE BPB - -;; ENTRY POINT -_start: - jmp BOOT_SEG:$+5 ; Fix the cs:ip registers with a vaudou magical trip - -bootstrap: - jmp go - -;; LOVELY DATA -FileNotFound db "First Stage ERROR : NO LOADER", 0 -DiskError db "First Stage ERROR : DISK", 0 -UserData dw 0 -Bootdrv db 0 -filename db "LOADER BIN" - - -;; GO ! -go: - mov ax, BOOT_SEG ; Set segments to the location of the bootloader - mov ds, ax - mov es, ax - - ;; INIT STACK - cli - mov ax, STACK_SEG ; Init the stack - mov ss, ax ; Continue init the stack - mov sp, STACK_OFF ; Ok man, the stack is in 4K :O - sti - mov bp, (0x7c0-STACK_SEG) << 4 ; Correct bp (the disk description table) - - ;; INITIALIZE BOOT DISK - or dl, dl ; Verifying dl points actually to the boot drive - jz load_root - mov byte [Bootdrv], dl ; Another soul (the disk) saved! - mov ah, 0x08 - int 0x13 ; int 0x13 : read drive parameters/geom - jc load_root - and cx, 0x003f ; Maximum sector number is the high bits 6-7 of cl - mov word [sectorsPerTrack], cx ; And whose low 8 bits are in ch - mov dl, dh ; Convert the maximum head number to a word with another vaudou magical trip - xor dh, dh - inc dx ; because head numbers start at zero - mov word [heads], dx ; Another soul (the heads number) saved! - - - ;; LOAD THE ROOT DIRECTORY FROM DISK -load_root: - xor cx, cx - mov ax, 32 ; Size of root dir = (rootDirEntries * 32) / bytesPerSector - mul word [rootDirEntries] ; multiply by the total size of the root directory - div word [bytesPerSector] ; divide by the number of bytes used per sector - xchg cx, ax - - mov al, byte [fats] ; Location of root dir = (fats * fatSectors) + reservedSectors - mul word [fatSectors] ; multiply by the sectors used - add ax, word [reservedSectors] ; increase ax by the reserved sectors - mov word [UserData], ax ; Start of user data = startOfRoot + numberOfRoot - add word [UserData], cx ; Add the size and location of the root directory - - mov di, BUFFER_SEG ; Set the extra segment to the disk buffer - mov es, di - mov di, BUFFER_OFF ; Set es:di and load the root directory into the disk buffer - call read_sectors ; Read the sectors - - ;; FIND THE SECOND STAGE LOADER - mov di, BUFFER_OFF ; Set es:di to the disk buffer - mov cx, word [rootDirEntries] ; Search through all of the root dir entries - xor ax, ax ; Clear ax for the file entry offset - -search_root: - xchg cx, dx ; Save cx because it's a loop counter - mov si, filename ; Load the filename - mov cx, 11 ; Compare first 11 bytes - rep cmpsb ; Compare si and di cx times - je load_fat ; We found the loader - add ax, 32 ; File entry offset - mov di, BUFFER_OFF ; Point back to the start of the entry - add di, ax ; Add the offset to point to the next entry - xchg dx, cx - loop search_root ; Continue to search for the file - - ;; ERROR... - mov si, FileNotFound ; Could not find the file - call print - call reboot - - ;; LOAD THE FAT FROM THE FILE -load_fat: - mov ax, word [es:di + 15] ; Get the file cluster at offset 26 - push ax ; Store the FAT cluster - xor ax, ax ; Size of fat = (fats * fatSectors) - mov al, byte [fats] ; Move number of fats into al - mul word [fatSectors] ; Move fat sectors into bx - mov cx, ax ; Store in cx - mov ax, word [reservedSectors] ; Convert the first fat on the disk - mov di, BUFFER_OFF ; Set es:di and load the fat sectors into the disk buffer - call read_sectors ; Read the sectors - - ;; LOAD THE CLUSTERS OF THE LOADER AND JUMP - mov di, LOAD_SEG - mov es, di ; Set es:bx to where the file will load - mov di, LOAD_OFF - pop ax ; File cluster restored - call read_clusters ; Read clusters from the file - mov dl, byte [Bootdrv] ; Pass the boot Bootdrv into dl - jmp LOAD_SEG:LOAD_OFF ; Jump to the file loaded! - - hlt ; This should never be hit... - ; ... - ; ... - ; I hope.... - ; ... - call reboot - -%include "boot/mbr/mbr.inc" - -;; END - times 510 - ($ - $$) db 0 ; Pad remainder of boot sector with zeros - dw 0xaa55 ; Boot signature diff --git a/boot/mbr/mbr.inc b/boot/mbr/mbr.inc deleted file mode 100644 index b006cce..0000000 --- a/boot/mbr/mbr.inc +++ /dev/null @@ -1,177 +0,0 @@ -;=----------------------------------------------------------------------------=; -; GNU GPL OS/K ; -; ; -; Desc: Bootsector for OS/K INCLUDED FUNCTIONS ; -; (x86_64 architecture only) ; -; ; -; ; -; Copyright © 2018-2019 The OS/K Team ; -; ; -; This file is part of OS/K. ; -; ; -; OS/K is free software: you can redistribute it and/or modify ; -; it under the terms of the GNU General Public License as published by ; -; the Free Software Foundation, either version 3 of the License, or ; -; any later version. ; -; ; -; OS/K is distributed in the hope that it will be useful, ; -; but WITHOUT ANY WARRANTY; without even the implied warranty of ; -; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; -; GNU General Public License for more details. ; -; ; -; You should have received a copy of the GNU General Public License ; -; along with OS/K. If not, see . ; -;=----------------------------------------------------------------------------=; - -[BITS 16] - -read_clusters: -;---------------------------------------------------; -; Read file clusters, starting at the given cluster,; -; expects FAT to be loaded into the disk buffer. ; -; Please note that this may allocate up to 128KB ; -; of ram. ; -; ; -; Expects: AX = Starting cluster ; -; ES:DI = Location to load clusters ; -; ; -; Returns: None ; -; ; -;---------------------------------------------------; - pusha - push es - .cluster_loop: - xor bh, bh - xor dx, dx - push ax ; Get the cluster start = (cluster - 2) * sectorsPerCluster + UserData - sub ax, 2 ; Subtract 2 - mov bl, byte [sectorsPerCluster] ; Sectors per cluster is a byte value - mul bx ; multiply (cluster - 2) * sectorsPerCluster - add ax, word [UserData] ; add the UserData - xor ch, ch - mov cl, byte [sectorsPerCluster] ; Sectors to read - call read_sectors ; Read the sectors - pop ax ; Current cluster number - xor dx, dx - ;; Calculate next sector for FAT16 (cluster * 2) - mov bx, 2 ; Multiply the cluster by two (cluster is in ax) - mul bx - ;; Load sector in RAM - push ds - push si - mov si, BUFFER_SEG - mov ds, si ; Temporarly set ds:si to the FAT buffer - mov si, BUFFER_OFF - add si, ax ; Point to the next cluster in the FAT entry - mov ax, word [ds:si] ; Load ax to the next cluster in FAT - pop si - pop ds - ;; Next - cmp ax, 0xfff8 ; Check if we are at the end of the file? - jae .done - add di, 512 ; Add to the pointer offset - jnc .cluster_loop - ;; Correct the buffer because an error will occur if the buffer in memory - mov dx, es ; overlaps a 64k page boundry, when di overflows - add dh, 0x10 ; it will trigger the carry flag, so correct - mov es, dx ; extra segment by 0x1000 - jmp .cluster_loop ; Load the next file cluster - .done: - pop es - popa - ret - - -read_sectors: -;---------------------------------------------------; -; Read sectors starting at a given sector by ; -; the given times and load into a buffer. Please ; -; note that this may allocate up to 128KB of ram. ; -; ; -; Expects: AX = Starting sector ; -; CX = Number of sectors to read ; -; ES:DI = Location to load sectors ; -; ; -; Returns: None ; -; ; -;---------------------------------------------------; - pusha - push es - mov bx, di ; Convert es:di to es:bx for int 13h - .sector_loop: - push ax - push cx - xor dx, dx - div word [sectorsPerTrack] ; Divide the lba (value in ax) by sectorsPerTrack - mov cx, dx ; Save the absolute sector value - inc cx - xor dx, dx ; Divide by the number of heads - div word [heads] ; to get absolute head and track values - mov dh, dl ; Move the absolute head into dh - mov ch, al ; Low 8 bits of absolute track - shl ah, 1 ; High 2 bits of absolute track - shl ah, 1 - shl ah, 1 - shl ah, 1 - shl ah, 1 - shl ah, 1 - or cl, ah ; Now cx is set with respective track and sector numbers - mov dl, byte [Bootdrv] ; Set correct Bootdrv for int 13h - mov di, 21 ; Try five times to read the sector because I love 21 - .attempt_read: - mov ax, 0x0201 ; Read Sectors func of int 13h, read one sector - int 0x13 ; Call int 13h (BIOS disk I/O) - jnc .read_ok ; If no carry set, the sector has been read - xor ah, ah ; Reset Bootdrv func of int 13h - int 0x13 ; Call int 13h (BIOS disk I/O) - dec di ; Decrease read attempt counter - jnz .attempt_read ; Try to read the sector again - mov si, DiskError ; Error reading the disk :/ - call print - jmp reboot - .read_ok: - pop cx - pop ax - inc ax ; Increase the next sector to read - add bx, word [bytesPerSector] ; Add to the buffer address for the next sector - jnc .next_sector - ;; Fixing buffer because an error will occur if the buffer in memory - mov dx, es ; overlaps a 64k page boundry, when bx overflows - add dh, 0x10 ; it will trigger the carry flag, so correct - mov es, dx ; es segment by 0x1000 - .next_sector: - loop .sector_loop - pop es - popa - ret - -print: -;---------------------------------------------------; -; Print out a simple string. ; -; ; -; Expects: DS:SI = String to print ; -; ; -; Returns: None ; -; ; -;---------------------------------------------------; - lodsb ; Load byte from ds:si to al - or al, al ; If al is empty stop looping - jz .done ; Done looping and return - mov ah, 0x0e ; Teletype output - int 0x10 ; Video interupt - jmp print ; Loop untill string is null - .done: - ret - -reboot: - xor ax, ax - int 0x16 ; Get a single keypress - mov ah, 0x0e ; Teletype output - mov al, 0x0d ; Carriage return - int 0x10 ; Video interupt - mov al, 0x0a ; Line feed - int 0x10 ; Video interupt - mov al, 0x0a ; Line feed - int 0x10 ; Video interupt - xor ax, ax - int 0x19 ; Reboot the system diff --git a/build/bin/disk.img b/build/bin/disk.img deleted file mode 100644 index 1dc81cd..0000000 Binary files a/build/bin/disk.img and /dev/null differ diff --git a/build/bin/loader.bin b/build/bin/loader.bin deleted file mode 100644 index 6ca87c7..0000000 Binary files a/build/bin/loader.bin and /dev/null differ diff --git a/build/bin/mbr.bin b/build/bin/mbr.bin deleted file mode 100644 index 37ff74f..0000000 Binary files a/build/bin/mbr.bin and /dev/null differ diff --git a/build/obj/boot/loader.bin b/build/obj/boot/loader.bin index 6ca87c7..e12a50a 100644 Binary files a/build/obj/boot/loader.bin and b/build/obj/boot/loader.bin differ