@@ -105,6 +105,40 @@ impl GlobalDescriptorTable {
105
105
}
106
106
}
107
107
108
+ /// Forms a GDT from a slice of `u64`.
109
+ ///
110
+ /// # Safety
111
+ ///
112
+ /// * The user must make sure that the entries are well formed
113
+ /// * The provided slice **must not be larger than 8 items** (only up to the first 8 will be observed.)
114
+ #[ inline]
115
+ #[ cfg( feature = "const_fn" ) ]
116
+ pub const unsafe fn from_raw_slice ( slice : & [ u64 ] ) -> GlobalDescriptorTable {
117
+ assert ! (
118
+ slice. len( ) <= 8 ,
119
+ "initializing a GDT from a slice requires it to be **at most** 8 elements."
120
+ ) ;
121
+ let next_free = slice. len ( ) ;
122
+
123
+ let mut table = [ 0 ; 8 ] ;
124
+ let mut idx = 0 ;
125
+
126
+ while idx != next_free {
127
+ table[ idx] = slice[ idx] ;
128
+ idx += 1 ;
129
+ }
130
+
131
+ GlobalDescriptorTable { table, next_free }
132
+ }
133
+
134
+ /// Get a reference to the internal table.
135
+ ///
136
+ /// The resulting slice may contain system descriptors, which span two `u64`s.
137
+ #[ inline]
138
+ pub fn as_raw_slice ( & self ) -> & [ u64 ] {
139
+ & self . table [ ..self . next_free ]
140
+ }
141
+
108
142
const_fn ! {
109
143
/// Adds the given segment descriptor to the GDT, returning the segment selector.
110
144
///
@@ -144,9 +178,27 @@ impl GlobalDescriptorTable {
144
178
#[ cfg( feature = "instructions" ) ]
145
179
#[ inline]
146
180
pub fn load ( & ' static self ) {
147
- use crate :: instructions:: tables:: lgdt;
148
181
// SAFETY: static lifetime ensures no modification after loading.
149
- unsafe { lgdt ( & self . pointer ( ) ) } ;
182
+ unsafe { self . load_unsafe ( ) } ;
183
+ }
184
+
185
+ /// Loads the GDT in the CPU using the `lgdt` instruction. This does **not** alter any of the
186
+ /// segment registers; you **must** (re)load them yourself using [the appropriate
187
+ /// functions](crate::instructions::segmentation):
188
+ /// [load_ss](crate::instructions::segmentation::load_ss),
189
+ /// [set_cs](crate::instructions::segmentation::set_cs).
190
+ ///
191
+ /// # Safety
192
+ ///
193
+ /// Unlike `load` this function will not impose a static lifetime constraint
194
+ /// this means its up to the user to ensure that there will be no modifications
195
+ /// after loading and that the GDT will live for as long as it's loaded.
196
+ ///
197
+ #[ cfg( feature = "instructions" ) ]
198
+ #[ inline]
199
+ pub unsafe fn load_unsafe ( & self ) {
200
+ use crate :: instructions:: tables:: lgdt;
201
+ lgdt ( & self . pointer ( ) ) ;
150
202
}
151
203
152
204
const_fn ! {
0 commit comments