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 should bump you way over 512 bytes I would imagine.
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.
you are right. Though with the partition table in there so u can support a 'modern' AHCI controller and SATA it will shrink your bootloader further and require some optimizations.... - you don't have 510 bytes for the loader in this case but a bunch less. if you want to populate the table with valid entries then it becomes even more tricky (can't use any bytes inside of the table...)
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.
Oh, cool. I never knew that was possible. Showing my ignorance here, but assuming we're just trying to get to long mode, why would we tour through protected mode at all?
The 80286 has the Machine Status Word (MSW), a 16 bit register. The 80386 expands this to CR0, a 32 bits register. Then 64 bit long mode adds the EFER MSR and expands CR0 to 64 bits. But even today only 11 bits of CR0 are in use and EFER has 8 active bits. I wonder why intel/AMD did not simply use the free bits of the existing register, and made that decision twice?
Probably for more robust backwards compatibility with software that might assume a given value for or write to the reserved bits. The assignment of bits to registers like this in the hardware is pretty arbitrary, there's not really any cost to using the higher bits
The one-word answer is probably "bureaucracy". Large groups of people just don't tend to make particularly good decisions overall, and a lot of nonsensical choices arise from that.
Ditto for why CR1 and 5-7 are still "reserved" and CR8 came into existence.
The most unnecessarily complicated thing in this article to me is the Makefile and linker script. NASM supports generating flat binary output, but apparently using it would be too "hacky"?
Later on, make files and linker scripts are an important headache. but when generating flat binary, just generate flat binary! No need to bloat it.
My OS used to have a file called make.sh to tease at this :D Now i am using a 'fileformat' and other fancy things and alas -fbin and --oformat=binary are but fleeting memories. I tried a long time to write separate data c files and code c files, dump it out to binary, and then building some monstrosity from there but it gets really difficult to link&load etc. xD --- better to just use the ELFs or PEs! I suppose that is litteraly what they do for u ;P
This seems both cool, and a good exercise, but is it useful? Does it have a UX like a fisher/price toy that you can verify/change your settings on the fly?
Booting is the process of going from mini-me mode/single user/recovery mode to flying.
I have been running Unix along side a Microsoft product since Xenix/dos. ( Looks like 40 years...) How much have we advanced?
I also have been using Linux since the swedish version came out ( first release ) and GNU 0.1.
My apologies about calling Xenix, Unix, It is a has-been wanna-be me-too square-excrament from shortly after release until it's languishing demise.
Microsoft does not release products, they empty their cat
boxes onto customers. ( The most recent example is both co-pilot And 22H2. )
If you look at how F1 cars have evolved, and pencils as well as pocket calculators - how close are we to the usable ideal?
Why isn't the bootloader a static kernel mode? It used to be. Someone recently suggested it should be, and I agreed.
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 scratch as 64 bit
it will not have any need for backwards compatibility and
would enter the required state by default?
I guess sthat was the goal / design of Itanium?
are made to start in the desired 64 bit state
from th
This is what Intel's proposed X86S [0] is designed for.
> X86S is a legacy-reduced-OS ISA that removes outdated execution modes and operating system
ISA.
> The presence of the X86S ISA is enumerated by a single, main CPUID feature
LEGACY_REDUCED_ISA in CPUID 7.1.ECX[2] which implies all the ISA removals described in this document. A new, 64-bit “start-up” interprocessor interrupt (SIPI) has a separate CPUID feature flag.
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.
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.
A laudable project. UEFI proponents here wondering why the person bothered to create a new bootloader approach might be missing the point of why people undertake such tasks as this. As the writer ends:
No. UEFI firmware creates a completely different environment for a UEFI bootloader than the legacy BIOS environment (real-address mode). The UEFI firmware enters 64-bit long mode directly on modern systems, and sets up a flat memory model GDT, as well as identity-mapped paging.
Only in the sense that every board vendor does their own random thing, which makes it simpler for the board vendors and horribly complicated for everyone else.
Yes. Bootloaders are still complex, but there is less legacy setup that is required. That said, if you're targeting UEFI instead of BIOS, it's a great deal simpler on x86 as well.
5-|1 year ago
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.
dataflow|1 year ago
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 should bump you way over 512 bytes I would imagine.
ChickeNES|1 year ago
sim7c00|1 year ago
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.
xelxebar|1 year ago
D4ckard|1 year ago
hyperman1|1 year ago
https://wiki.osdev.org/CPU_Registers_x86-64#CR0.
rcxdude|1 year ago
userbinator|1 year ago
Ditto for why CR1 and 5-7 are still "reserved" and CR8 came into existence.
rep_lodsb|1 year ago
darby_nine|1 year ago
sim7c00|1 year ago
Later on, make files and linker scripts are an important headache. but when generating flat binary, just generate flat binary! No need to bloat it.
My OS used to have a file called make.sh to tease at this :D Now i am using a 'fileformat' and other fancy things and alas -fbin and --oformat=binary are but fleeting memories. I tried a long time to write separate data c files and code c files, dump it out to binary, and then building some monstrosity from there but it gets really difficult to link&load etc. xD --- better to just use the ELFs or PEs! I suppose that is litteraly what they do for u ;P
ForOldHack|1 year ago
Booting is the process of going from mini-me mode/single user/recovery mode to flying.
I have been running Unix along side a Microsoft product since Xenix/dos. ( Looks like 40 years...) How much have we advanced?
I also have been using Linux since the swedish version came out ( first release ) and GNU 0.1.
My apologies about calling Xenix, Unix, It is a has-been wanna-be me-too square-excrament from shortly after release until it's languishing demise.
Microsoft does not release products, they empty their cat boxes onto customers. ( The most recent example is both co-pilot And 22H2. )
If you look at how F1 cars have evolved, and pencils as well as pocket calculators - how close are we to the usable ideal?
Why isn't the bootloader a static kernel mode? It used to be. Someone recently suggested it should be, and I agreed.
blankx32|1 year ago
ThinkBeat|1 year ago
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 scratch as 64 bit it will not have any need for backwards compatibility and would enter the required state by default?
I guess sthat was the goal / design of Itanium?
are made to start in the desired 64 bit state from th
nullindividual|1 year ago
> X86S is a legacy-reduced-OS ISA that removes outdated execution modes and operating system ISA.
> The presence of the X86S ISA is enumerated by a single, main CPUID feature LEGACY_REDUCED_ISA in CPUID 7.1.ECX[2] which implies all the ISA removals described in this document. A new, 64-bit “start-up” interprocessor interrupt (SIPI) has a separate CPUID feature flag.
[0] https://cdrdv2.intel.com/v1/dl/getContent/776648 [pdf warning]
userbinator|1 year ago
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.
LiamPowell|1 year ago
saagarjha|1 year ago
cf100clunk|1 year ago
> Cool if you actually came along this far.
Cool indeed.
AstralStorm|1 year ago
deaddodo|1 year ago
Deprecated doesn't mean deleted, it just means "no longer updated/developed with a goal towards removal".
ruslan|1 year ago
khaledh|1 year ago
I've written about creating a UEFI bootloader (for my hobby OS) here: https://0xc0ffee.netlify.app/osdev/05-bootloader-p1.html
amelius|1 year ago
rwmj|1 year ago
surajrmal|1 year ago
gtirloni|1 year ago