blob: a9808aa073a601e90dca05f81b2d7847e5023e4e (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
#include "gdt.h"
void encodeGDT(uint8_t* gdtEntry, struct GDT source) {
if ((source.limit > 65536) && ((source.limit & 0xFFF) == 0xFFF)) {
// Set the GDT to use paging
// To do this we need to make sure the limit is aligned to 4KiB
source.limit = source.limit >> 12;
// Granularity: 1 (use paging with 4KiB segments)
// Size: 1 (32 bit protected mode)
gdtEntry[6] = 0xC0;
}
else {
// Granularity: 0 (1 byte segments)
// Size: 1
gdtEntry[6] = 0x40;
}
// Here we are encoding the limit
// Bits 0-15 encode the bottom 16 bits of the limit
gdtEntry[0] = source.limit & 0xFF;
gdtEntry[1] = (source.limit >> 8) & 0xFF;
// Bits 48-51 encode the last 4 bits of the limit
gdtEntry[6] |= (source.limit >> 16) & 0xF;
// Bits 16-39 encode the bottom 24 bits of the base
gdtEntry[2] = source.base & 0xFF;
gdtEntry[3] = (source.base >> 8) & 0xFF;
gdtEntry[4] = (source.base >> 16) & 0xFF;
// Bits 56-64 encode the last byte of the base
gdtEntry[7] = (source.base >> 24) & 0xFF;
// Bits 40-47 set the access byte, which is documented at https://wiki.osdev.org/GDT,
// where most of the ideas for this function are taken from shamelessly
gdtEntry[5] = source.type;
}
|