Skip to content

Commit

Permalink
gdt: Move GDT and GDT Definitions to Rust
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
josephlr committed Apr 9, 2020
1 parent 317cf22 commit 016322e
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 35 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ log-serial = []
log-panic = ["log-serial"]

[dependencies]
bitflags = "1.2"
x86_64 = "0.9"
atomic_refcell = "0.1"
r-efi = "2.1.0"
Expand Down
32 changes: 0 additions & 32 deletions src/asm/gdt64.s

This file was deleted.

1 change: 0 additions & 1 deletion src/asm/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
global_asm!(include_str!("ram32.s"));
global_asm!(include_str!("ram64.s"));
global_asm!(include_str!("gdt64.s"));
4 changes: 2 additions & 2 deletions src/asm/ram32.s
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,6 @@ enable_paging:
jump_to_64bit:
# We are now in 32-bit compatibility mode. To enter 64-bit mode, we need to
# load a 64-bit code segment into our GDT.
lgdtl gdt64_ptr
lgdtl GDT64_PTR
# Set CS to a 64-bit segment and jump to 64-bit code.
ljmpl $(code64_desc - gdt64_start), $ram64_start
ljmpl $0x08, $ram64_start
53 changes: 53 additions & 0 deletions src/gdt.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
use core::mem::size_of;

bitflags::bitflags! {
// An extension of x86_64::structures::gdt::DescriptorFlags
struct Descriptor: u64 {
const LIMIT_0_15 = 0xFFFF;
const BASE_0_23 = 0xFF_FFFF << 16;
const ACCESSED = 1 << 40;
const WRITABLE = 1 << 41; // Only for Data-Segments
const READABLE = 1 << 41; // Only for Code-Segments
const EXPANSION = 1 << 42; // Only for Data-Segments
const CONFORMING = 1 << 42; // Only for Code-Segments
const EXECUTABLE = 1 << 43;
const USER_SEGMENT = 1 << 44;
const DPL_RING_3 = 3 << 45;
const PRESENT = 1 << 47;
const LIMIT_16_19 = 0xF << 48;
const SOFTWARE = 1 << 52;
const BIT64 = 1 << 53;
const BIT32 = 1 << 54;
const GRANULARITY = 1 << 55;
const BASE_24_31 = 0xFF << 56;

// All segments are nonconforming, non-system, ring-0 only, and present.
// We set ACCESSED in advance to avoid writing to the descriptor.
const COMMON = Self::ACCESSED.bits | Self::USER_SEGMENT.bits | Self::PRESENT.bits;
// BIT32 must be 0, all other bits (not yet mentioned) are ignored.
const CODE64 = Self::COMMON.bits | Self::EXECUTABLE.bits | Self::BIT64.bits;
}
}

// An alternative to x86_64::structures::DescriptorTablePointer that avoids
// "pointer-to-integer cast" (which rust does not support in statics).
#[repr(C, packed)]
struct Pointer {
limit: u16,
base: &'static Descriptor,
}

impl Pointer {
const fn new(gdt: &'static [Descriptor]) -> Self {
let size = gdt.len() * size_of::<Descriptor>();
Self {
limit: size as u16 - 1,
base: &gdt[0],
}
}
}

// Our 64-bit GDT lives in RAM, so it can be accessed like any other global.
#[no_mangle]
static GDT64_PTR: Pointer = Pointer::new(&GDT64);
static GDT64: [Descriptor; 2] = [Descriptor::empty(), Descriptor::CODE64];
1 change: 1 addition & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ mod boot;
mod bzimage;
mod efi;
mod fat;
mod gdt;
mod loader;
mod mem;
mod paging;
Expand Down

0 comments on commit 016322e

Please sign in to comment.