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