CLOSE

One of the challenges in operating system (OS) development is loading a kernel or a second stage loader that is larger than 1MB. The conventional real mode environment, which is the initial state of x86 processors, imposes a memory addressing limit of 1MB. This constraint complicates the process of loading larger binaries. This article will explore the problem and discuss two common solutions: using compressed kernels and leveraging unreal mode.

The 1MB Limit in Real Mode

In real mode, the x86 processor can only address memory using 20-bit addresses, allowing access to a maximum of 1MB. This includes all system memory from 0x00000 to 0xFFFFF. However, not all of this memory is available for kernel loading as some portions are reserved for system use (BIOS data, interrupt vectors, etc.).

The Problem

Modern kernels and second stage loaders often exceed the 1MB limit due to their complexity and the need to include various functionalities. Developers need to find ways to load these larger binaries into memory efficiently, ensuring that the transition from the bootloader to the operating system is seamless.

Solutions

Two effective methods to address this problem are compressing the kernel and using unreal mode.

Method 1: Compressing the Kernel

Compressing the kernel reduces its size so it fits within the 1MB limit of real mode. Once loaded, the kernel can decompress itself into higher memory regions.

Steps to Compress the Kernel:

  1. Compress the Kernel: Use a compression tool like gzip to reduce the kernel size.
  2. Modify the Bootloader: Adjust the bootloader to load the compressed kernel.
  3. Decompress the Kernel: Implement a decompression routine in the bootloader or in the initial part of the kernel.

Method 2: Using Unreal Mode

Unreal mode allows access to memory beyond 1MB while still operating in a 16-bit environment. This is achieved by briefly switching to protected mode to set segment limits, and then returning to real mode with extended segment limits.

Steps to Enter Unreal Mode:

  1. Enter Protected Mode: Set up the Global Descriptor Table (GDT) and switch to protected mode.
  2. Set Segment Limits: Adjust segment limits to access more than 1MB of memory.
  3. Return to Real Mode: Switch back to real mode with extended segment limits.

References:

http://nuclear.mutantstargoat.com/articles/pcmetal/pcmetal03.html