diff --git a/Makefile b/Makefile index c1270d4..789f65f 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ -ARCH = x86 -SUBSYSTEM = 10 +ARCH = x64 +SUBSYSTEM = 10 ifeq ($(shell uname -m),x86_64) MINGW_HOST = w64 @@ -12,22 +12,22 @@ ifeq ($(ARCH),x64) GCC_ARCH = x86_64 QEMU_ARCH = x86_64 FW_BASE = OVMF - CROSS_COMPILE = $(GCC_ARCH)-$(MINGW_HOST)-mingw32- + #CROSS_COMPILE = $(GCC_ARCH)-$(MINGW_HOST)-mingw32- + CROSS_COMPILE = EP_PREFIX = C_FLAGS = -m64 -mno-red-zone - LD_FLAGS = -Wl,-dll -Wl,--subsystem,$(SUBSYSTEM) + LD_FLAGS = -Wl,-dll #-Wl,--subsystem,$(SUBSYSTEM) endif CC := $(CROSS_COMPILE)gcc -OBJCOPY := $(CROSS_COMPILE)objcopy AS := $(CROSS_COMPILE)as -LK := $(CROSS_COMPILE)gcc +LD := $(CROSS_COMPILE)gcc OC := $(CROSS_COMPILE)objcopy -CC_DIR = src/arch/$(ARCH)/c -INC_DIR = src/arch/$(ARCH)/h -AS_DIR = src/arch/$(ARCH)/s -OBJ_DIR = bin/arch/$(ARCH)/o +CC_DIR = src/arch/$(GCC_ARCH)/c +INC_DIR = src/arch/$(GCC_ARCH)/h +AS_DIR = src/arch/$(GCC_ARCH)/s +OBJ_DIR = bin/arch/$(GCC_ARCH)/o GNUEFI_DIR = ../gnu-efi @@ -37,33 +37,32 @@ C_DEFS = -DCONFIG_$(GNUEFI_ARCH) -D__MAKEWITH_GNUEFI -DGNU_EFI_USE_MS_ABI LD_FLAGS += -s -Wl,-Bsymbolic -nostdlib -shared LD_LIB += -L$(GNUEFI_DIR)/$(GNUEFI_ARCH)/lib -e $(EP_PREFIX)efi_main -LIBS = -lefi $(CRT0_LIBS) +LIBS = -lefi -lgnuefi +QEMU = qemu-system-$(QEMU_ARCH) +#LK_DOC = $(GNU_EFI_DIR)/gnuefi/elf_x86_64_efi.lds +#LK_DOC = linker.ld +#LK_FLAGS = -nostdlib -shared,-T,$(LK_DOC) -Wl,-Bsymbolic -Wl,-znocombreloc +#LIB_SEARCH = -L$(GNU_EFI_DIR)/x86_64/lib -L$(GNU_EFI_DIR)/x86_64/gnuefi -LK_DOC = $(GNU_EFI_DIR)/gnuefi/elf_x86_64_efi.lds -LK_DOC = linker.ld -LK_FLAGS = -nostdlib -shared,-T,$(LK_DOC) -Wl,-Bsymbolic -Wl,-znocombreloc -LIB_SEARCH = -L$(GNU_EFI_DIR)/x86_64/lib -L$(GNU_EFI_DIR)/x86_64/gnuefi +CC_FILES_IN := $(wildcard $(CC_DIR)/*.c) +AS_FILES_IN := $(wildcard $(AS_DIR)/*.s) -CC_FILES_IN := $(wildcard $(CC_DIR)/*.c) -AS_FILES_IN := $(wildcard $(AS_DIR)/*.s) +CC_FILES_OUT = $(patsubst $(CC_DIR)/%.c, $(OBJ_DIR)/%.o, $(CC_FILES_IN)) +AS_FILES_OUT = $(patsubst $(AS_DIR)/%.s, $(OBJ_DIR)/%.o, $(AS_FILES_IN)) -CC_FILES_OUT=$(patsubst $(CC_DIR)/%.c, $(OBJ_DIR)/%.o, $(CC_FILES_IN)) -AS_FILES_OUT=$(patsubst $(AS_DIR)/%.s, $(OBJ_DIR)/%.o, $(AS_FILES_IN)) +BIN = novos_$(ARCH) +BIN_OUT = bin/$(BIN) +EFI_OUT = bin/arch/$(GCC_ARCH)/BOOT$(ARCH).EFI -BIN = novos -BIN_OUT = bin/$(BIN) -EFI_OUT = bin/arch/$(ARCH)/BOOTX64.EFI +ISO = $(BIN_OUT).iso +FAT_IMG = $(BIN_OUT).img -ISO = $(BIN_OUT).iso -FAT_IMG = $(BIN_OUT).img +OVMF_DIR = OVMF +OVMF_FIRMWARE = $(OVMF_DIR)/OVMF-pure-efi.fd -OVMF_DIR = OVMF - -QEMU_DRIVER = $(OVMF_DIR)/OVMF-pure-efi.fd -OVMF_CODE = $(OVMF_DIR)/OVMF_CODE-pure-efi.fd -OVMF_VARS = $(OVMF_DIR)/OVMF_VARS-pure-efi.fd +all: $(EFI_OUT) obj_dir: @[ -d $(OBJ_DIR) ] || mkdir $(OBJ_DIR) -p @@ -72,21 +71,26 @@ $(OBJ_DIR)/%.o: $(CC_DIR)/%.c obj_dir @echo Compiling $<... @$(CC) $(C_FLAGS) $(C_INC) $(C_DEFS) -o $@ -c $< -build: $(CC_FILES_OUT) $(AS_FILES_OUT) obj_dir +$(EFI_OUT): $(CC_FILES_OUT) $(AS_FILES_OUT) obj_dir @echo Linking... - @$(LK) $(LK_FLAGS) $(LIB_SEARCH) -o $(BIN_OUT).elf $(AS_FILES_OUT) $(CC_FILES_OUT) -lgnuefi -lefi -lgcc - @$(OC) -I elf64-x86-64 -O efi-app-x86_64 $(BIN_OUT).elf $(EFI_OUT) + @$(LD) $(LD_FLAGS) $(LD_LIB) -o $(BIN_OUT).elf $(AS_FILES_OUT) $(CC_FILES_OUT) $(LIBS) + #@$(OC) -I elf64-x86-64 -O efi-app-x86_64 $(BIN_OUT).elf $(EFI_OUT) + @mkdir -p bin/arch/$(GCC_ARCH) + @$(OC) -j .text -j .sdata -j .data -j .dynamic -j .dynsym -j .rel* -j .rela* -j .reloc -j .eh_frame -O binary $(BIN_OUT).elf $(EFI_OUT) @echo Link success. - -fat: build +$(FAT_IMG): $(EFI_OUT) @echo Building FAT image... - @dd if=/dev/zero of=$(FAT_IMG) bs=1k count=1440 - @mformat -i $(FAT_IMG) -f 1440 :: - @mmd -i $(FAT_IMG) ::/EFI - @mmd -i $(FAT_IMG) ::/EFI/BOOT - @mcopy -i $(FAT_IMG) $(EFI_OUT) ::/EFI/BOOT - @cp $(FAT_IMG) $(BIN).img + @dd if=/dev/zero of=$@ bs=1k count=1440 + @mformat -i $@ -f 1440 :: + @mmd -i $@ ::/EFI + @mmd -i $@ ::/EFI/BOOT + @mcopy -i $@ $(EFI_OUT) ::/EFI/BOOT + @cp $@ $(BIN).img + + @mkdir -p image/efi/boot + @cp -f $(EFI_OUT) image/efi/boot/BOOT$(ARCH).EFI + @echo Done. harddrive: fat @@ -101,19 +105,5 @@ clean: @rm -f $(BIN).bin @echo Cleaned. -emulate: fat - #qemu-system-i386 -bios $(OVMF_FLASH) -hda $(BIN).bin -serial file:serial.log - - #qemu-system-i386 -machine q35 -m 256 -smp 2 -net none \ - #-global driver=$(QEMU_DRIVER),property=secure,value=on \ - #-drive if=pflash,format=raw,unit=0,file=$(OVMF_CODE),readonly=on \ - #-drive if=pflash,format=raw,unit=1,file=$(OVMF_VARS) \ - #-drive if=ide,format=raw,file=$(BIN).img - - #qemu-system-x86_64 -machine q35 -m 256 -smp 2 -net none \ - #-global driver=$(QEMU_DRIVER),property=secure,value=on \ - #-drive if=pflash,format=raw,unit=0,file=$(OVMF_CODE),readonly=on \ - #-drive if=pflash,format=raw,unit=1,file=$(OVMF_VARS) \ - #-drive if=ide,format=raw,file=$(BIN).img - - qemu-system-x86_64 -pflash $(QEMU_DRIVER) -drive if=ide,format=raw,file=$(BIN).img -net none -serial file:serial.log \ No newline at end of file +emulate: $(FAT_IMG) + $(QEMU) $(QEMU_FLAGS) -bios $(OVMF_FIRMWARE) -net none -hda fat:rw:image -serial file:serial.log \ No newline at end of file diff --git a/build_toolchain.sh b/build_toolchain.sh index a93eddb..11005de 100755 --- a/build_toolchain.sh +++ b/build_toolchain.sh @@ -8,12 +8,13 @@ make cd .. -export TARGET=x86_64-elf +export TARGET=x86_64-w64-mingw32 export TARGETS=$TARGET,x86_64-pe export PREFIX=/opt/cross/$TARGET export PATH="$PREFIX/bin:$PATH" +rm -fr build-binutils mkdir build-binutils cd build-binutils ../binutils-*/configure --target=$TARGET --enable-targets=$TARGETS --prefix="$PREFIX" --with-sysroot --disable-nls @@ -22,6 +23,7 @@ sudo make install cd .. +rm -fr build-gcc mkdir build-gcc cd build-gcc ../gcc-*/configure --target=$TARGET --prefix="$PREFIX" --disable-nls --enable-languages=c,c++ --without-headers @@ -30,5 +32,4 @@ make all-target-libgcc sudo make install-gcc sudo make install-target-libgcc - echo "prefix is $PREFIX" \ No newline at end of file diff --git a/image/NvVars b/image/NvVars new file mode 100644 index 0000000..51582b7 Binary files /dev/null and b/image/NvVars differ diff --git a/image/efi/boot/BOOTx64.EFI b/image/efi/boot/BOOTx64.EFI new file mode 100644 index 0000000..a8c8df1 Binary files /dev/null and b/image/efi/boot/BOOTx64.EFI differ diff --git a/novos_x64.img b/novos_x64.img new file mode 100644 index 0000000..3956205 Binary files /dev/null and b/novos_x64.img differ diff --git a/serial.log b/serial.log index 1e4c62c..cb8e91d 100644 --- a/serial.log +++ b/serial.log @@ -7,9 +7,127 @@ EDK II UEFI v2.70 (EDK II, 0x00010000) Mapping table  FS0: Alias(s):HD0a1:;BLK1: - PciRoot(0x0)/Pci(0x1,0x1)/Ata(0x0)/HD(1,MBR,0x00000000,0x0,0xB40) + PciRoot(0x0)/Pci(0x1,0x1)/Ata(0x0)/HD(1,MBR,0xBE1AFDFA,0x3F,0xFBFC1)  BLK0: Alias(s): PciRoot(0x0)/Pci(0x1,0x1)/Ata(0x0)  BLK2: Alias(s): PciRoot(0x0)/Pci(0x1,0x1)/Ata(0x0) -Press ESC in 5 seconds to skip startup.nsh or any other key to continue.Press ESC in 4 seconds to skip startup.nsh or any other key to continue. \ No newline at end of file +Press ESC in 5 seconds to skip startup.nsh or any other key to continue.Press ESC in 4 seconds to skip startup.nsh or any other key to continue.Press ESC in 3 seconds to skip startup.nsh or any other key to continue.Press ESC in 2 seconds to skip startup.nsh or any other key to continue.Press ESC in 1 seconds to skip startup.nsh or any other key to continue. +Shell> [=3h[=3h[=3h[=3hBdsDxe: failed to load Boot0001 "UEFI QEMU DVD-ROM QM00003 " from PciRoot(0x0)/Pci(0x1,0x1)/Ata(Secondary,Master,0x0): Not Found +BdsDxe: failed to load Boot0002 "UEFI QEMU HARDDISK QM00001 " from PciRoot(0x0)/Pci(0x1,0x1)/Ata(Primary,Master,0x0): Not Found +BdsDxe: loading Boot0003 "EFI Internal Shell" from Fv(7CB8BDC9-F8EB-4F34-AAEA-3EE4AF6516A1)/FvFile(7C04A583-9E3E-4F1C-AD65-E05268D0B4D1) +BdsDxe: starting Boot0003 "EFI Internal Shell" from Fv(7CB8BDC9-F8EB-4F34-AAEA-3EE4AF6516A1)/FvFile(7C04A583-9E3E-4F1C-AD65-E05268D0B4D1) +UEFI Interactive Shell v2.2 +EDK II +UEFI v2.70 (EDK II, 0x00010000) +Mapping table + FS0: Alias(s):HD0a1:;BLK1: + PciRoot(0x0)/Pci(0x1,0x1)/Ata(0x0)/HD(1,MBR,0xBE1AFDFA,0x3F,0xFBFC1) + BLK0: Alias(s): + PciRoot(0x0)/Pci(0x1,0x1)/Ata(0x0) + BLK2: Alias(s): + PciRoot(0x0)/Pci(0x1,0x1)/Ata(0x0) +Press ESC in 5 seconds to skip startup.nsh or any other key to continue. +Shell> gui +'gui' is not recognized as an internal or external command, operable program, or script file. +Shell> help +alias - Displays, creates, or deletes UEFI Shell aliases. +attrib - Displays or modifies the attributes of files or directories. +bcfg - Manages the boot and driver options that are stored in NVRAM. +cd - Displays or changes the current directory. +cls - Clears the console output and optionally changes the background and foreground color. +comp - Compares the contents of two files on a byte-for-byte basis. +connect - Binds a driver to a specific device and starts the driver. +cp - Copies one or more files or directories to another location. +date - Displays and sets the current date for the system. +dblk - Displays one or more blocks from a block device. +devices - Displays the list of devices managed by UEFI drivers. +devtree - Displays the UEFI Driver Model compliant device tree. +dh - Displays the device handles in the UEFI environment. +disconnect - Disconnects one or more drivers from the specified devices. +dmem - Displays the contents of system or device memory. +dmpstore - Manages all UEFI variables. +drivers - Displays the UEFI driver list. +drvcfg - Invokes the driver configuration. +drvdiag - Invokes the Driver Diagnostics Protocol. +echo - Controls script file command echoing or displays a message. +edit - Provides a full screen text editor for ASCII or UCS-2 files. +eficompress - Compresses a file using UEFI Compression Algorithm. +efidecompress - Decompresses a file using UEFI Decompression Algorithm. +else - Identifies the code executed when 'if' is FALSE. +endfor - Ends a 'for' loop. +endif - Ends the block of a script controlled by an 'if' statement. +exit - Exits the UEFI Shell or the current script. +for - Starts a loop based on 'for' syntax. +getmtc - Gets the MTC from BootServices and displays it. +goto - Moves around the point of execution in a script. +help - Displays the UEFI Shell command list or verbose command help. +hexedit - Provides a full screen hex editor for files, block devices, or memory. +http - Download a file from HTTP server. +if - Executes commands in specified conditions. +ifconfig - Modifies the default IP address of the UEFI IPv4 Network Stack. +ifconfig6 - Displays or modifies IPv6 configuration for network interface. +initrd - Registers or unregisters a file as Linux initrd. +load - Loads a UEFI driver into memory. +loadpcirom - Loads a PCI Option ROM. +ls - Lists the contents of a directory or file information. +map - Displays or defines file system mappings. +memmap - Displays the memory map maintained by the UEFI environment. +mkdir - Creates one or more new directories. +mm - Displays or modifies MEM/MMIO/IO/PCI/PCIE address space. +mode - Displays or changes the console output device mode. +mv - Moves one or more files to a destination within or between file systems. +openinfo - Displays the protocols and agents associated with a handle. +parse - Retrieves a value from a standard format output file. +pause - Pauses a script and waits for an operator to press a key. +pci - Displays PCI device list or PCI function configuration space and PCIe extended +configuration space. +ping - Ping the target host with an IPv4 stack. +ping6 - Ping a target machine with UEFI IPv6 network stack. +reconnect - Reconnects drivers to the specific device. +reset - Resets the system. +rm - Deletes one or more files or directories. +sermode - Sets serial port attributes. +set - Displays or modifies UEFI Shell environment variables. +setsize - Adjusts the size of a file. +setvar - Displays or modifies a UEFI variable. +shift - Shifts in-script parameter positions. +smbiosview - Displays SMBIOS information. +stall - Stalls the operation for a specified number of microseconds. +tftp - Download a file from TFTP server. +time - Displays or sets the current time for the system. +timezone - Displays or sets time zone information. +touch - Updates the filename timestamp with the current system date and time. +type - Sends the contents of a file to the standard output device. +unload - Unloads a driver image that was already loaded. +ver - Displays UEFI Firmware version information. +vol - Displays or modifies information about a disk volume. + +Help usage:help [cmd|pattern|special] [-usage] [-verbose] [-section name][-b] +Shell> devices + T D + Y C I + P F A +CTRL E G G #P #D #C Device Name +==== = = = == == === ========================================================= + 33 R - - 0 1 5 PciRoot(0x0) + 66 D - - 2 0 0 Primary Console Input Device + 67 D - - 2 0 0 Primary Console Output Device + 68 D - - 1 0 0 Primary Standard Error Device + 9F D - - 1 0 0 PciRoot(0x0)/Pci(0x0,0x0) + A0 B - - 1 1 3 PciRoot(0x0)/Pci(0x1,0x0) + A1 B - - 1 4 2 Sata Controller + A2 D - - 1 0 0 PciRoot(0x0)/Pci(0x1,0x3) + A3 B - - 1 1 1 QEMU Video PCI Adapter + A5 B - - 1 3 1 PciRoot(0x0)/Pci(0x2,0x0)/AcpiAdr(0x80010100) + A8 B - - 1 1 1 PciRoot(0x0)/Pci(0x1,0x0)/Serial(0x0) + A9 D - - 1 0 0 PciRoot(0x0)/Pci(0x1,0x0)/Serial(0x1) + AA B - - 1 3 1 PS/2 Keyboard Device + AB B - - 1 1 1 SIO Serial Port #0 + AC B - - 1 5 3 PC-ANSI Serial Console + AD B - - 1 2 1 QEMU HARDDISK + AE D - - 1 2 0 SCSI Disk Device + AF D - - 1 2 0 FAT File System +Shell> n bcgf  fg +bcfg: Too few arguments. +Shell>  \ No newline at end of file diff --git a/src/arch/x86_64/c/efimain.c b/src/arch/x86_64/c/efimain.c new file mode 100644 index 0000000..b2755c1 --- /dev/null +++ b/src/arch/x86_64/c/efimain.c @@ -0,0 +1,33 @@ +#include +#include + +EFI_STATUS efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) +{ + EFI_STATUS Status; + EFI_INPUT_KEY Key; + + /* Store the system table for future use in other functions */ + ST = SystemTable; + const char * test = "BEANS"; + + /* Say hi */ + Status = ST->ConOut->OutputString(ST->ConOut, L"Hello World\n\r"); + if (EFI_ERROR(Status)) + return Status; + + /* Now wait for a keystroke before continuing, otherwise your + message will flash off the screen before you see it. + + First, we need to empty the console input buffer to flush + out any keystrokes entered before this point */ + Status = ST->ConIn->Reset(ST->ConIn, FALSE); + if (EFI_ERROR(Status)) + return Status; + + /* Now wait until a key becomes available. This is a simple + polling implementation. You could try and use the WaitForKey + event instead if you like */ + while ((Status = ST->ConIn->ReadKeyStroke(ST->ConIn, &Key)) == EFI_NOT_READY) ; + + return Status; +} \ No newline at end of file