Search code examples
assemblyx86bootloaderosdevbios

Confusion regarding CS and DS segment registers during bootloading process


I've been learning about OS development by following the MIT course with JOS.Right now, I'm digging into how bootloaders work and the details of x86 computer architecture, especially memory segmentation.I recently encountered a point of confusion regarding the behaviour of segment registers during the bootloading process.

I've understood that when a computer boots up, the BIOS initializes the system and loads the bootloader into memory from the boot device, typically starting at physical address 0x7C00. The bootloader then takes over and begins executing, eventually loading the operating system.

My confusion arises regarding the behavior of the CS (Code Segment) and DS (Data Segment) registers during this process. Here's what I understand so far:

  1. Initially, when the CPU begins executing instructions from the BIOS, the CS register points to the segment containing the BIOS code, and the DS register points to a default segment used by the BIOS for data operations.

  2. When the BIOS loads the bootloader into memory at address 0x7C00 and transfers control to it, the CPU begins executing instructions from the bootloader code.

Here's where my confusion starts:

  • Once the BIOS completes loading the bootloader into memory and transfers control to it, does the CPU's CS segment register still point to the BIOS segment, or does it now point to the segment where the bootloader is loaded (e.g., 0x7C00)?

  • If the CPU was executing BIOS code just before this transition and the bootloader code is considered data at that moment, would the segment where the bootloader resides be considered a data segment? So does this mean both CS and DS registers end up pointing to the same memory address after this transition, how does the CPU differentiate between code and data in this scenario?

  • At this point, which segment does the CS register point to? Is it updated to point to the segment where the bootloader code resides (i.e., the segment containing address 0x7C00)? Or does it still point to the BIOS code segment?

  • Similarly, what about the DS register? Does it point to the segment where the bootloader data resides, or does it retain its original value, pointing to the BIOS data segment?

I've read various resources and tutorials on bootloader development, but I haven't found a clear explanation of how segment registers are handled during this transition from BIOS to bootloader.

Could someone please provide a detailed explanation of how CS and DS registers are managed during the bootloading process? Any insights, explanations, or resources would be greatly appreciated.


Solution

  • The CPU executes the code at CS:IP. Therefore, to execute the code of the bootloader, CS has to point to the bootloader. If CS:IP pointed to the BIOS, the CPU would be executing that BIOS instruction.

    The bootloader code is code, not data. You seem to misunderstand the segment registers. The 8086 has a 1 MB address space, but CS and DS only point to 64 kB segments. You also have SS, the stack, and an extra ES, but that still isn't enough to access the entire 1 MB at once. That's why you can change the segment registers on the fly.

    The 8086 itself does not differentiate between code and data. You can have CS=DS, and in fact this is a common setup. The CPU still isn't going to execute random stuff from that segment, but only the instruction at CS:IP.

    Code can set DS to whatever is convenient. The BIOS has no idea what works for the bootloader, so it doesn't try to be smart.