mirror of
https://github.com/cfenollosa/os-tutorial.git
synced 2025-12-18 04:44:35 +03:00
lessons 8, 9, 10, entering 32-bit mode
This commit is contained in:
35
09-32bit-gdt/32bit-gdt.asm
Normal file
35
09-32bit-gdt/32bit-gdt.asm
Normal file
@@ -0,0 +1,35 @@
|
||||
gdt_start: ; don't remove the labels, they're needed to compute sizes and jumps
|
||||
; the GDT starts with a null 8-byte
|
||||
dd 0x0 ; 4 byte
|
||||
dd 0x0 ; 4 byte
|
||||
|
||||
; GDT for code segment. base = 0x00000000, length = 0xfffff
|
||||
; for flags, refer to os-dev.pdf document, page 36
|
||||
gdt_code:
|
||||
dw 0xffff ; segment length, bits 0-15
|
||||
dw 0x0 ; segment base, bits 0-15
|
||||
db 0x0 ; segment base, bits 16-23
|
||||
db 10011010b ; flags (8 bits)
|
||||
db 11001111b ; flags (4 bits) + segment length, bits 16-19
|
||||
db 0x0 ; segment base, bits 24-31
|
||||
|
||||
; GDT for data segment. base and length identical to code segment
|
||||
; some flags changed, again, refer to os-dev.pdf
|
||||
gdt_data:
|
||||
dw 0xffff
|
||||
dw 0x0
|
||||
db 0x0
|
||||
db 10010010b
|
||||
db 11001111b
|
||||
db 0x0
|
||||
|
||||
gdt_end:
|
||||
|
||||
; GDT descriptor
|
||||
gdt_descriptor:
|
||||
dw gdt_end - gdt_start - 1 ; size (16 bit), always one less of its true size
|
||||
dd gdt_start ; address (32 bit)
|
||||
|
||||
; define some constants for later use
|
||||
CODE_SEG equ gdt_code - gdt_start
|
||||
DATA_SEG equ gdt_data - gdt_start
|
||||
31
09-32bit-gdt/README.md
Normal file
31
09-32bit-gdt/README.md
Normal file
@@ -0,0 +1,31 @@
|
||||
*Concepts you may want to Google beforehand: GDT*
|
||||
|
||||
**Goals: program the GDT**
|
||||
|
||||
Remember segmentation from lesson 6? The offset was left shifted
|
||||
to address an extra level of indirection.
|
||||
|
||||
In 32-bit mode, segmentation works differently. Now, the offset becomes an
|
||||
index to a segment descriptor (SD) in the GDT. This descriptor defines
|
||||
the base address (32 bits), the size (20 bits) and some flags, like
|
||||
readonly, permissions, etc. To add confusion, the data structures are split,
|
||||
so open the os-dev.pdf file and check out the figure on page 34 or the
|
||||
Wikipedia page for the GDT.
|
||||
|
||||
The easiest way to program the GDT is to define two segments, one for code
|
||||
and another for data. These can overlap which means there is no memory protection,
|
||||
but it's good enough to boot, we'll fix this later with a higher language.
|
||||
|
||||
As a curiosity, the first GDT entry must be `0x00` to make sure that the
|
||||
programmer didn't make any mistakes managing addresses.
|
||||
|
||||
Furthermore, since the CPU needs to know how long the GDT is, we'll use
|
||||
a meta structure called the "GDT descriptor" with the size (16b) and address
|
||||
(32b) of our actual GDT.
|
||||
|
||||
Let's directly jump to the GDT code in assembly. Again, to understand
|
||||
all the segment flags, refer to the os-dev.pdf document. The theory for
|
||||
this lesson is quite complex.
|
||||
|
||||
In the next lesson we will make the switch to 32-bit protected mode
|
||||
and test our code from these lessons.
|
||||
Reference in New Issue
Block a user