Skip to content

Commit f578136

Browse files
committed
gdt: Move GDT and GDT Definitions to Rust
The GDT is just some data in static memory, so there's not a good reason to have this code in assembly. Ideally, we would use types from the x86_64 crate for this. However, - We can't use x86_64::structures::gdt::DescriptorFlags for the contents of the descriptors, as that definition is missing flags. - We can't use x86_64::structures::DescriptorTablePointer for the GDT pointers because its base is a u64, and Rust doesn't allow "pointer-to-integer cast" in statics. So we have to roll our own. The definitions aren't that bad. The only downside is that we have to add the bitflags dependency, but it was already a dependancy of x86_64, so that's also not bad. Signed-off-by: Joe Richey <[email protected]>
1 parent fb1dbcb commit f578136

File tree

7 files changed

+58
-35
lines changed

7 files changed

+58
-35
lines changed

Cargo.lock

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ log-serial = []
2424
log-panic = ["log-serial"]
2525

2626
[dependencies]
27+
bitflags = "1.2"
2728
x86_64 = "0.9"
2829
atomic_refcell = "0.1"
2930
r-efi = "2.1.0"

src/asm/gdt64.s

-32
This file was deleted.

src/asm/mod.rs

-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
11
global_asm!(include_str!("ram32.s"));
22
global_asm!(include_str!("ram64.s"));
3-
global_asm!(include_str!("gdt64.s"));

src/asm/ram32.s

+2-2
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,6 @@ enable_paging:
4141
jump_to_64bit:
4242
# We are now in 32-bit compatibility mode. To enter 64-bit mode, we need to
4343
# load a 64-bit code segment into our GDT.
44-
lgdtl gdt64_ptr
44+
lgdtl GDT64_PTR
4545
# Set CS to a 64-bit segment and jump to 64-bit code.
46-
ljmpl $(code64_desc - gdt64_start), $ram64_start
46+
ljmpl $0x08, $ram64_start

src/gdt.rs

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
use core::mem::size_of;
2+
3+
bitflags::bitflags! {
4+
// An extension of x86_64::structures::gdt::DescriptorFlags
5+
struct Descriptor: u64 {
6+
const LIMIT_0_15 = 0xFFFF;
7+
const BASE_0_23 = 0xFF_FFFF << 16;
8+
const ACCESSED = 1 << 40;
9+
const WRITABLE = 1 << 41; // Only for Data-Segments
10+
const READABLE = 1 << 41; // Only for Code-Segments
11+
const EXPANSION = 1 << 42; // Only for Data-Segments
12+
const CONFORMING = 1 << 42; // Only for Code-Segments
13+
const EXECUTABLE = 1 << 43;
14+
const USER_SEGMENT = 1 << 44;
15+
const DPL_RING_3 = 3 << 45;
16+
const PRESENT = 1 << 47;
17+
const LIMIT_16_19 = 0xF << 48;
18+
const SOFTWARE = 1 << 52;
19+
const BIT64 = 1 << 53;
20+
const BIT32 = 1 << 54;
21+
const GRANULARITY = 1 << 55;
22+
const BASE_24_31 = 0xFF << 56;
23+
24+
// All segments are nonconforming, non-system, ring-0 only, and present.
25+
// We set ACCESSED in advance to avoid writing to the descriptor.
26+
const COMMON = Self::ACCESSED.bits | Self::USER_SEGMENT.bits | Self::PRESENT.bits;
27+
// BIT32 must be 0, all other bits (not yet mentioned) are ignored.
28+
const CODE64 = Self::COMMON.bits | Self::EXECUTABLE.bits | Self::BIT64.bits;
29+
}
30+
}
31+
32+
// An alternative to x86_64::structures::DescriptorTablePointer that avoids
33+
// "pointer-to-integer cast" (which rust does not support in statics).
34+
#[repr(C, packed)]
35+
struct Pointer {
36+
limit: u16,
37+
base: &'static Descriptor,
38+
}
39+
40+
impl Pointer {
41+
const fn new(gdt: &'static [Descriptor]) -> Self {
42+
let size = gdt.len() * size_of::<Descriptor>();
43+
Self {
44+
limit: size as u16 - 1,
45+
base: &gdt[0],
46+
}
47+
}
48+
}
49+
50+
// Our 64-bit GDT lives in RAM, so it can be accessed like any other global.
51+
#[no_mangle]
52+
static GDT64_PTR: Pointer = Pointer::new(&GDT64);
53+
static GDT64: [Descriptor; 2] = [Descriptor::empty(), Descriptor::CODE64];

src/main.rs

+1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ mod boot;
3737
mod bzimage;
3838
mod efi;
3939
mod fat;
40+
mod gdt;
4041
mod loader;
4142
mod mem;
4243
mod paging;

0 commit comments

Comments
 (0)