Skip to content

Commit

Permalink
Toss out the bootloader; lay down the foundation of UEFI and x86-64 s…
Browse files Browse the repository at this point in the history
…upport
  • Loading branch information
portasynthinca3 committed Dec 21, 2019
1 parent 15c6bae commit 0740284
Show file tree
Hide file tree
Showing 133 changed files with 12,187 additions and 1,220 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
.git/
.vscode/
build/
.gitignore
usb.vmdk
createusbvmdk.sh
usbvmdk.sh
bochsout.txt
bx_enh_dbg.ini
23 changes: 2 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,35 +9,16 @@ This project is **not** intended to do some crazy stuff like replacing the giant
# Who is involved?
* Me, Andrey Antonenko, the creator, maintainer and programmer
* Sasha Kulichkov, booted this on his PC several times; created the logo
# What parts does this consist of?
1. First stage loader, called Muon-1
2. Second stage loader, called Muon-2
3. The monolithic kernel. So monolithic in fact, that all the system processes, even the graphics, are integrated. It's called Quark.
4. The font converter. Written in C#
5. The custom builder. Written in Python.
# Where does it work?
In theory, it should work on any modern system. Here are the minimal requirements:
* CPU: Pentium 4 or later
* RAM: 32 MB
* Buses: PCI, ATA
* An empty internal hard drive to boot from. You will be able to boot from external USB sticks, disk drives, floppies, etc., but
as the kernel only has ATA support right now, it woudn't be able to read any data from any drives except ATA drives or SATA
drives in ATA compatibility mode (can almost certainly be enabled in the BIOS)
* Legacy BIOS system or an UEFI system with legacy emulation mode
* A video card supporting VESA 1.2 standard (integrated CPU graphics should also work)\
* An UEFI system. Neutron up to version 0.1.11 was a legacy BIOS system, but I had switched over to UEFI for future expanadability.
\
Also, there are some detected problems:
* Some very modern systems only have UEFI support, totally eliminating the legacy BIOS standard. Neutron can't be booted on those systems.
# Show me the screenshots!
Okay, there you go!\
![boot1](https://github.com/portasynthinca3/neutron/blob/master/screens/boot_1.png "boot1")\
*Boot screen 1*\
![boot2](https://github.com/portasynthinca3/neutron/blob/master/screens/boot_2.png "boot2")\
*Boot screen 2*\
![desktop](https://github.com/portasynthinca3/neutron/blob/master/screens/desktop.png "desktop")\
*Desktop*
![shutdown](https://github.com/portasynthinca3/neutron/blob/master/screens/sdown.png "shutdown")\
*Shutdown prompt*
They are in the `screens` directory
# Okay, what do I need to be aware of?
Keep in mind that the system is unstable. I am **not** responsible for **any** kind of damage.
However, please tell me if you have found a bug, especially if it's dangerous enough to do any damage. That would be very nice!
Expand Down
55 changes: 0 additions & 55 deletions bochsrc.txt

This file was deleted.

Binary file removed build/1stg.asm.bin
Binary file not shown.
Binary file removed build/2stg.asm.bin
Binary file not shown.
13 changes: 0 additions & 13 deletions build/lds

This file was deleted.

Binary file modified build/neutron.img
Binary file not shown.
Binary file removed build/obj/a20.s.o
Binary file not shown.
Binary file removed build/obj/acpi.c.o
Binary file not shown.
Binary file removed build/obj/ata.c.o
Binary file not shown.
Binary file removed build/obj/cbuild.o
Binary file not shown.
Binary file removed build/obj/diskio.c.o
Binary file not shown.
Binary file removed build/obj/gfx.c.o
Binary file not shown.
Binary file removed build/obj/gui.c.o
Binary file not shown.
Binary file removed build/obj/isr_wrapper.s.o
Binary file not shown.
Binary file removed build/obj/pci.c.o
Binary file not shown.
Binary file removed build/obj/pic.c.o
Binary file not shown.
Binary file removed build/obj/pit.c.o
Binary file not shown.
Binary file removed build/obj/ps2.c.o
Binary file not shown.
Binary file removed build/obj/ps2_kbd.c.o
Binary file not shown.
Binary file removed build/obj/quark.c.o
Binary file not shown.
Binary file removed build/obj/stdgui.c.o
Binary file not shown.
Binary file removed build/obj/stdlib.c.o
Binary file not shown.
Binary file removed build/obj/usb.c.o
Binary file not shown.
Binary file removed build/quark.bin
Binary file not shown.
166 changes: 42 additions & 124 deletions builder.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,39 @@
import sys, os

def get_object_files(dir_name):
list_of_files = os.listdir(dir_name)
all_files = list()
for entry in list_of_files:
full_path = os.path.join(dir_name, entry)
if os.path.isdir(full_path):
all_files += get_object_files(full_path)
elif full_path.endswith('.o'):
all_files.append(full_path)

return all_files

def get_c_files(dir_name):
list_of_files = os.listdir(dir_name)
all_files = list()
for entry in list_of_files:
full_path = os.path.join(dir_name, entry)
if os.path.isdir(full_path):
all_files += get_object_files(full_path)
elif full_path.endswith('.c'):
all_files.append(full_path)

return all_files

config_file = 'neutron.nbuild'
image_file = 'build/neutron.img'
image = bytearray(1440 * 1024)
image_size_sectors = 2880

config_file_obj = open(config_file, 'r')
config_contents = config_file_obj.read()
config_file_obj.close()

asm_files = list()
asm_stack_files = list()
c_files = list()
fs_files = list()
crawout = '<undefined>'

config_section = ''
config_lines = config_contents.split('\n')
Expand All @@ -22,139 +43,36 @@
if not line.startswith('#'):
if line.startswith('.'):
config_section = line[1:]
if not config_section in ['asm', 'c', 'fs', 'crawout']:
if not config_section in ['c', 'fs']:
print('Error at ' + config_file + ':' + str(line_no + 1) + ': invalid section "' + config_section + '"')
sys.exit()
else:
if config_section == 'asm':
if line.endswith(' --no-append'):
asm_files.append(line[:-len(' --no-append')])
else:
asm_stack_files.append(line)
elif config_section == 'c':
if config_section == 'c':
c_files.append(line)
elif config_section == 'fs':
fs_files.append(line)
elif config_section == 'crawout':
if crawout != '<undefined>':
print('Error at ' + config_file + ':' + str(line_no + 1) + ': section "' + config_section + '" can only contain one entry')
sys.exit()
else:
crawout = line
else:
print('Error at ' + config_file + ':' + str(line_no + 1) + ': data in invalid section "' + config_section + '"')
sys.exit()

print('Assembling stacking binaries')
stack_pos = 0
for path in asm_stack_files:
path_bin = 'build/' + os.path.basename(path) + '.bin'
print(' Assembling: ' + path + ' -> ' + path_bin)
os.system('yasm -f bin -o ' + path_bin + ' ' + path)

print(' Stacking: ' + path_bin)
bin_file = open(path_bin, 'rb')
bin_file_cont = bin_file.read()
bin_file.close()
for byte in bin_file_cont:
image[stack_pos] = byte
stack_pos = stack_pos + 1

print('Assembling ordinary binaries')
for path in asm_files:
path_bin = 'build/' + os.path.basename(path) + '.bin'
print(' Assembling: ' + path + ' -> ' + path_bin)
os.system('yasm -f bin -o ' + path_bin + ' ' + path)

c_obj = list()
print('Generating C object files')
c_obj.append('gnu-efi/x86_64/gnuefi/libgnuefi.a')
c_obj.append('gnu-efi/x86_64/lib/libefi.a')
print('Compiling C sources')
for path in c_files:
path_obj = 'build/obj/' + os.path.basename(path) + '.o'
path_obj = 'build/' + os.path.basename(path) + '.o'
c_obj.append(path_obj)
print(' Compiling: ' + path + ' -> ' + path_obj)
#So, hear me out.
#I literally spent more than two days trying to find out why my code doesn't work in VirtualBox
# but does so in Bochs.
#It turned out to be a VirtualBox coding error. A newer ENDBR32 instruction is supposed to enhance the branch
# prediction mechanism preformance on modern CPUs and is placed by GCC at the start of all functions. Older CPUs should
# decode ENDBR32 as REP MULTIBYTE NOP, and that's exactly what Bochs does, so no problems there. But! VirtualBox decodes
# it as a sequence of an illegal opcode and STI. I don't have a proper interrupt servicing mechanism yet, so this
# creates a huge problem. I spent all this time just to find out why Neutron would crash randomly in absolutely
# random places. The -fcf-protection=branch -mmanual-endbr options are here to prevent GCC from placing
# ENDBR32. It could improve performance, in theory, but I disabled this feature solely for the sake of compatibility.
#https://stackoverflow.com/questions/56120231/how-do-old-cpus-execute-the-new-endbr64-and-endbr32-instructions/59219143#59219143
os.system('cc -o ' + path_obj + ' ' + path + ' -m32 -c -nostdlib -nodefaultlibs -Og -ffunction-sections -fcf-protection=branch -mmanual-endbr')

print('Linking C object files')
print(' Generating liker script')
ld_script = open('build/lds', 'w')
#ld_script.write('SECTIONS {\n.text 0x00000F00 : {\n' + ' (.text)\n'.join(c_obj) + ' (.text)\n}\n.data : {\n' + ' (.data)\n'.join(c_obj) + ' (.data)\n}\n}')
ld_script.write('ENTRY(main)\nSECTIONS\n{\n\t.text 0x00000F00 :\n\t{\n\t\t*(.text.main);\n\t\t*(.text*);\n\t}\n\t.data :\n\t{\n\t\t*(.data*);\n\t}\n}')
ld_script.close()
print(' Invoking linker')
os.system('ld -o build/obj/cbuild.o ' + ' '.join(c_obj) + ' --entry=main -melf_i386 -nostdlib -n -T build/lds')

print('Generating raw binary')
os.system('objcopy -O binary build/obj/cbuild.o ' + crawout)

if len(fs_files) > 0:
print('Building nFS')
print(' Writing signature')
image[4608] = 0x00
image[4609] = 0xF5
image[4610] = 0xAD
image[4611] = 0xDE

print(' Writing partition name')
part_name = 'Neutron Test FS'
for i in range(len(part_name)):
c = part_name[i]
image[4612 + i] = ord(c)

print(' Writing Master FileTable')
file_sects = list()
next_f_sect = 11
for path in fs_files:
if path != "":
path_src = path.split('>')[0]
path_dst = path.split('>')[1]
f_size = os.path.getsize(path_src)
f_size_sect = f_size // 512
if f_size_sect % 512 > 0:
f_size_sect = f_size_sect + 1
file_sects.append(next_f_sect)

print(' Writing entry for: ' + path_dst)
for i in range(len(path_dst)):
c = path_dst[i]
image[5120 + (fs_files.index(path) * 32) + i] = ord(c)

image[5120 + (fs_files.index(path) * 32) + 24] = f_size & 0xFF
image[5120 + (fs_files.index(path) * 32) + 25] = (f_size >> 8) & 0xFF
image[5120 + (fs_files.index(path) * 32) + 26] = (f_size >> 16) & 0xFF
image[5120 + (fs_files.index(path) * 32) + 27] = (f_size >> 24) & 0xFF
image[5120 + (fs_files.index(path) * 32) + 28] = next_f_sect & 0xFF
image[5120 + (fs_files.index(path) * 32) + 29] = (next_f_sect >> 8) & 0xFF
image[5120 + (fs_files.index(path) * 32) + 30] = (next_f_sect >> 16) & 0xFF
image[5120 + (fs_files.index(path) * 32) + 31] = (next_f_sect >> 24) & 0xFF

next_f_sect = next_f_sect + f_size_sect
os.system('x86_64-w64-mingw32-gcc -ffreestanding -m64 -Ignu-efi/inc -Ignu-efi/lib -Ignu-efi/inc/x86_64 -Ignu-efi/inc/protocol -nostdlib -c -o ' + path_obj + ' ' + path)

print(' Writing files')
for path in fs_files:
if path != "":
path_src = path.split('>')[0]
path_dst = path.split('>')[1]
print(' Writing file: ' + path_dst)
bin_file = open(path_src, 'rb')
bin_file_cont = bin_file.read()
bin_file.close()
stack_pos = 0
for byte in bin_file_cont:
image[(file_sects[fs_files.index(path)] * 512) + stack_pos] = byte
stack_pos = stack_pos + 1
print('Linking')
os.system('x86_64-w64-mingw32-gcc -m64 -nostdlib -Wl,-dll -shared -Wl,--subsystem,10 -e efi_main -o build/BOOTX64.EFI ' + ' '.join(c_obj) + ' -lgcc')

print('Writing image to: ' + image_file)
image_file_file = open(image_file, 'wb')
image_file_file.write(image)
image_file_file.close()
print('Bulding system image')
print(' Creating image file')
os.system('dd if=/dev/zero of=build/neutron.img count=' + str(image_size_sectors) + ' > /dev/null')
os.system('mformat -i build/neutron.img -f ' + str(image_size_sectors / 2))
print(' Creating filesystem')
os.system('mmd -i build/neutron.img ::/EFI')
os.system('mmd -i build/neutron.img ::/EFI/BOOT')
os.system('mcopy -i build/neutron.img build/BOOTX64.EFI ::/EFI/BOOT')
26 changes: 0 additions & 26 deletions bx_enh_dbg.ini

This file was deleted.

Loading

0 comments on commit 0740284

Please sign in to comment.