I'm having difficulties understanding how a simple boot loader works. The boot loader I'm talking about is the one from MITs course "Operating Systems Engineering".
First, let me show you a piece of assembly code the BIOS executes:
[f000:fec3] 0xffec3: lidtw %cs:0x7908
[f000:fec9] 0xffec9: lgdtw %cs:0x7948
[f000:fecf] 0xffecf: mov %cr0,%eax
[f000:fed2] 0xffed2: or $0x1,%eax
[f000:fed6] 0xffed6: mov %eax,%cr0
[f000:fed9] 0xffed9: ljmpl $0x8,$0xffee1
From the looks of it, This code sets up the interrupt table and the descriptor table and then turns on the protected mode.
- Why do we go into protected mode in the BIOS? Shouldn't the bootloader run in real mode (btw - why does it need to run in real mode?)
- I searched but didn't find anywhere exactly how the ljmpl instruction works, and is the difference between it and ljmp and regular jmp - I would appreciate if someone would point in the right direction.
- Why do we perform the jump? What is the purpose of this instruction?
Moving on to the boot loader code -
# Switch from real to protected mode, using a bootstrap GDT
# and segment translation that makes virtual addresses
# identical to their physical addresses, so that the
# effective memory map does not change during the switch.
lgdt gdtdesc
movl %cr0, %eax
orl $CR0_PE_ON, %eax
movl %eax, %cr0
# Jump to next instruction, but in 32-bit code segment.
# Switches processor into 32-bit mode.
ljmp $PROT_MODE_CSEG, $protcseg
- It says that the processor is in real mode - but we just saw that the BIOS switches to protected mode... I'm confused - how can this be possible?
- How do we switch to 32bit mode? What causes the processor to magically go into 32bit mode due to the ljmp instruction?
And another thing that I don't understand - when I track the execution of the bootloader with gdb I see the following instruction being executed (that's the ljmp instruction from the bootloader code):
ljmp $0x8,$0x7c32
But when I looked in the .asm file I saw the following:
ljmp $0xb866,$0x87c32
Totally lost here - How come the instruction written in the .asm file and the instruction executed are different? I have a hunch this has to do with the protected mode and how it translates the addresses but I don't really get it.
I would appreciate any help!