diff options
author | Kartik Agaram <vc@akkartik.com> | 2020-12-19 20:59:40 -0800 |
---|---|---|
committer | Kartik Agaram <vc@akkartik.com> | 2020-12-19 21:06:05 -0800 |
commit | a84fadd65d923fbb71c5c2b9884972114a0c2928 (patch) | |
tree | 1f8ae0f80656c86db8bedc28ba6c484dbf961626 /apps/bos/switch_to_pm.asm | |
parent | cbe8bfd87a4273993647ecdcd821e59521122c57 (diff) | |
download | mu-a84fadd65d923fbb71c5c2b9884972114a0c2928.tar.gz |
7355 - learning to boot into 32-bit mode
These exercises are from the incomplete "Writing a simple operating system from scratch" by Nick Blundell. https://www.cs.bham.ac.uk/~exr/lectures/opsys/10_11/lectures/os-dev.pdf
Diffstat (limited to 'apps/bos/switch_to_pm.asm')
-rw-r--r-- | apps/bos/switch_to_pm.asm | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/apps/bos/switch_to_pm.asm b/apps/bos/switch_to_pm.asm new file mode 100644 index 00000000..aeef97c0 --- /dev/null +++ b/apps/bos/switch_to_pm.asm @@ -0,0 +1,34 @@ +[bits 16] +; Switch to protected mode +switch_to_pm: + cli ; We must switch of interrupts until we have + ; set up the protected mode interrupt vector + ; otherwise interrupts will run riot. + + 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 + ; prefetched 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 |