All to me entirely unnecessary steps required to get the CPU into the correct mode is astounding. They all seem to be steps needed for backwards compatibility. Could Intel just provide a flag, command, to start in the right mode from the beginning. Or just remove all the backwards compatibility. I think I remember doing some research and ARM64 has some of the same issues. Are there any CPUs that are designed from scr…
Writing a BIOS bootloader for 64-bit mode from scratch
51–60 of 82 posts
Re: Writing a BIOS bootloader for 64-bit mode from scratch
#52note that you can switch to long mode directly, without going into protected mode first, with way less code: https://wiki.osdev.org/Entering_Long_Mode_Directly i've had a bootloader for a small 64-bit kernel based on this that fit comfortably into the bootsector, including loading the kernel from disk and setting up vesa modes, no stage2 required.
Or just use https://limine-bootloader.org/ , which greatly simplifies everything. No messing around in real mode (even when doing SMP), automatically loads your kernel using a higher-half mapping, and also works on aarch64 and riscv64.
Re: Writing a BIOS bootloader for 64-bit mode from scratch
#53All to me entirely unnecessary steps required to get the CPU into the correct mode is astounding. They all seem to be steps needed for backwards compatibility. Could Intel just provide a flag, command, to start in the right mode from the beginning. Or just remove all the backwards compatibility. I think I remember doing some research and ARM64 has some of the same issues. Are there any CPUs that are designed from scr…
Intel tried that with the 80376 and it did not go well: https://en.wikipedia.org/wiki/Intel_80376 Neither did the Itanium (Itanic). Backwards compatibility is the whole reason for choosing x86 over ARM, MIPS, RISC-V, etc. Sadly it seems some people at Intel and AMD don't realise this.
Re: Writing a BIOS bootloader for 64-bit mode from scratch
#54note that you can switch to long mode directly, without going into protected mode first, with way less code: https://wiki.osdev.org/Entering_Long_Mode_Directly i've had a bootloader for a small 64-bit kernel based on this that fit comfortably into the bootsector, including loading the kernel from disk and setting up vesa modes, no stage2 required.
Re: Writing a BIOS bootloader for 64-bit mode from scratch
#55note that you can switch to long mode directly, without going into protected mode first, with way less code: https://wiki.osdev.org/Entering_Long_Mode_Directly i've had a bootloader for a small 64-bit kernel based on this that fit comfortably into the bootsector, including loading the kernel from disk and setting up vesa modes, no stage2 required.
If you want to use an actual modern harddisk, you might want to look at GPT rather than MBR, as it won't overflow partition table stuff and allow for very large disks (2TB+?) (uefi gets rid of all of that and allows u to use a proper disk layout without any additional difficulty!)
there is no need for protected mode if you want to launch into 64-bit mode. I would say though, DO NOT USE BIOS. It's a piece of rubbish which will just make things more tedious.
Using UEFI via EDK2 or GnuEFI is the way to go, and both methods are really easy and a blessin to implement. It's a bit hard to get around the initial idea of UEFI, but if you view some other people's example projects on github you can find easily how it works. EDK is a bit shitty with .dec and .inf files etc, and GnuEFI is just reading headerfiles to discover what is there, but it's inifnitely better than the unspecified bios interface. You can litterally not even assume the int 0x10, int 0x15 etc. are there properly if you start running on real hardware. On UEFI systems, you can assume a stable minimal basis, and easily enumerate other things (hardware/platform capabilities etc.) in a sane way.
Also UEFI sets up the platform a long way already, so you don't need to do any initialization for your os-loader component (stage2 or 3). You can simply start loading your os right away. or drivers or whatever kind of design your kernel is. get memory map, get some access to efi file system, start pulling in and loading stuff.
Re: Writing a BIOS bootloader for 64-bit mode from scratch
#56Earlier quoted context omitted.
I vaguely recall there being some multicore stuff in UEFI, but it's been years since I looked at it.
Intel did a prototype of a multiprocessor UEFI application that would start up cores and UEFI itself does support synchronization on the assumption that applications/bootloaders will start other cores before calling ExitBootServices. However, there are no protocols as of 2.10 (the current spec[1]) that I can find that would bring up another processor. That said searching it can be a bit arcane. [1] https://uefi.org/s…
Re: Writing a BIOS bootloader for 64-bit mode from scratch
#57Earlier quoted context omitted.
UEFI exists. You just put a Windows-like binary in a folder on a partition and it runs in a hosted environment in 64-bit mode. And of course there's countless bootloaders that can take care of all this for you too.
And then you're free from dealing with the somewhat convoluted processor init stuff, but instead depend on the Windows PE format, FAT filesystem, and an overcomplicated API. Seems like a bad tradeoff, and part of a slippery slope towards a completely locked down system, where writing your own code and getting it to run on the 'bare metal' is flat out impossible.
Sometimes I wonder: if UEFI instead used ELF format, ext2 filesystem, and somewhat less complicated API (let's be honest: UEFI API is pretty straightforward if tedious), would people still complain about such dependencies? Or would it be deemed to be "fine" since it's not Microsoft technology even though it still would require one to use a multi-megabyte toolchain?
Re: Writing a BIOS bootloader for 64-bit mode from scratch
#58Is this any simpler on ARM?
Not sure, I wouldn't count on it. Currently deep in RISC-V and it seems there's hope.
Re: Writing a BIOS bootloader for 64-bit mode from scratch
#59note that you can switch to long mode directly, without going into protected mode first, with way less code: https://wiki.osdev.org/Entering_Long_Mode_Directly i've had a bootloader for a small 64-bit kernel based on this that fit comfortably into the bootsector, including loading the kernel from disk and setting up vesa modes, no stage2 required.
> i've had a bootloader for a small 64-bit kernel based on this that fit comfortably into the bootsector, including loading the kernel from disk and setting up vesa modes, no stage2 required. How in the world do you fit all that in 512 bytes? I'm guessing you don't have a real-world filesystem (that allows the kernel to be anywhere on the disk just as a normal file)? Because just dealing with file fragmentation shoul…
If you do this all within 1 sector, equally you do not do any error checking. just ram stuff into memory and yolojump into it.
the basic would be: load kernel from disk using bios interrupt get memory map using bios interrupt parse kernel ELF header / program headers and relocate it - elf header to find ph_off and ph_num and entry_point - program headers to find all pt_load and rep movb them into tgt phys addr.
Also with 510 bytes generally u will not make nice 'page tables' though this is actually possible with only few bytes. - i did not manage it yet in 510 :D but i am sure there's someone who can do it... it can be done really efficiently.
the disk would be formed by assemblding the mbr. then doing something like
cat mbr.bin kernel.bin > disk.bin (maybe here use truncate to padd the disk.bin to a certain size like 10+MB or so - helps some controllers recognize it better)
all that said it's not useful to do this. you will find it an interesting excersize at best. like trying to make 'tiny ELF' file or so. fun to learn, useless in practice.
Re: Writing a BIOS bootloader for 64-bit mode from scratch
#60Earlier quoted context omitted.
> i've had a bootloader for a small 64-bit kernel based on this that fit comfortably into the bootsector, including loading the kernel from disk and setting up vesa modes, no stage2 required. How in the world do you fit all that in 512 bytes? I'm guessing you don't have a real-world filesystem (that allows the kernel to be anywhere on the disk just as a normal file)? Because just dealing with file fragmentation shoul…
I've been thinking about how to structure a filesystem such that code complexity - in the boot loader and elsewhere - can be minimized. You'd want something similar to NTFS, except that it should be possible to refer to a file (MFT entry) directly by starting sector number. So they would either need to always remain at a fixed position, or have a link pointing back to any reference so it can be updated. Somewhere in…
not fragmenting files.... well. U don't fragment files until you do.. u know. If u write an FS it will only fragment what u tell it to. So if u want all contigious files then u can simply do it that way. store them as (file_id,sector_count,start). or even more simple (fname_len,fname,sector_count,start_sector) so u dont need to keep nameblock around for filenames (fat?)
If u look at Ext2/4, FAT16/32 and others u will see that it all started quite basically, keepin a list of files and offsets. But due to things like disk reliability, user errors, system stability issues etc., you need a lot of extra stuff.
Also, questions like : how long is a maximum for a filename length? This kind of stuff can really impact what kind of features u need to implement.
How long is a file allowed to be? How many files are maximum for the FS?
This might sound silly, but there's already datacenters out there (a lot actually) who cannot use most filesystems because either files are too huge, partitions are too huge, too many files are present for index structures etc.
If you want dead simple for a starting OS: (sector_count,start_sector,fname_len,fname,0)
If you want more, try looking at ext2 or FAT32 or if your system specifications require it, look even beyond. (ext4, ZFS, NTFS, etc.) - A lot of these are subtely different, trying to solve different problems, or similar problems in different ways.