-
Notifications
You must be signed in to change notification settings - Fork 56
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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]>
- Loading branch information
Showing
7 changed files
with
58 additions
and
35 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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")); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -37,6 +37,7 @@ mod boot; | |
mod bzimage; | ||
mod efi; | ||
mod fat; | ||
mod gdt; | ||
mod loader; | ||
mod mem; | ||
mod paging; | ||
|