Writing a Simple Operating System — from Scratch

(Jeff_L) #1

CHAPTER 4. ENTERING 32-BIT PROTECTED MODE 39


lgdt [gdt_descriptor] ; Load our global descriptor table , which defines
; the protected mode segments (e.g. for code and data)

mov eax , cr0 ; To make the switch to protected mode , we set
or eax , 0x1 ; the first bit of CR0 , a control register
mov cr0 , eax
jmp CODE_SEG:init_pm ; Make a far jump (i.e. to a new segment) to our 32-bit
; code. This also forces the CPU to flush its cache of
; pre -fetched and real -mode decoded instructions , which can
; cause problems.

[bits 32]
; Initialise registers and the stack once in PM.
init_pm:

mov ax, DATA_SEG ; Now in PM, our old segments are meaningless ,
mov ds, ax ; so we point our segment registers to the
mov ss, ax ; data selector we defined in our GDT
mov es, ax
mov fs, ax
mov gs, ax

mov ebp , 0x90000 ; Update our stack position so it is right
mov esp , ebp ; at the top of the free space.

call BEGIN_PM ; Finally , call some well -known label

4.5 Putting it all Together


Finally, we can include all of our routines into a boot sector that demonstrates the switch
from 16-bit real mode into 32-bit protected mode.


; A boot sector that enters 32-bit protected mode.
[org 0x7c00]

mov bp, 0x9000 ; Set the stack.
mov sp, bp

mov bx, MSG_REAL_MODE
call print_string

call switch_to_pm ; Note that we never return from here.

jmp $

%include "../print/print_string.asm"
%include "gdt.asm"
%include "print_string_pm.asm"
%include "switch_to_pm.asm"

[bits 32]
Free download pdf