title: bootloader - switching processor to protected mode
body: <p>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". </p>
  
  <p>First, let me show you a piece of assembly code the BIOS executes:</p>
  
  <pre><code>[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
  </code></pre>
  
  <p>From the looks of it, This code sets up the interrupt table and the descriptor table and then turns on the protected mode.  </p>
  
  <ol>
  <li>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?)</li>
  <li>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.</li>
  <li>Why do we perform the jump? What is
  the purpose of this instruction? </li>
  </ol>
  
  <p>Moving on to the boot loader code - </p>
  
  <pre><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
  </code></pre>
  
  <ol>
  <li>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?</li>
  <li>How do we switch to 32bit mode? What
  causes the processor to magically go
  into 32bit mode due to the ljmp
  instruction?</li>
  </ol>
  
  <p>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):</p>
  
  <pre><code>ljmp   $0x8,$0x7c32
  </code></pre>
  
  <p>But when I looked in the .asm file I saw the following:</p>
  
  <pre><code>ljmp   $0xb866,$0x87c32
  </code></pre>
  
  <p>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.</p>
  
  <p>I would appreciate any help!</p>