In Ubuntu 14.04 amd64, I dump the GDT info in a kernel module:
0000: NULL desc
0008: 32-bit CODE desc, DPL 0
0010: 64-bit CODE desc, DPL 0
0018: DATA desc, DPL 0
0020: 32-bit CODE desc, DPL 3
0028: DATA desc, DPL 3
0030: 64-bit CODE desc, DPL 3
0038: NULL desc
0040: busy TSS desc
0050: NULL desc
0058: NULL desc
0060: NULL desc
0068: NULL desc
0070: NULL desc
0078: 16-bit DATA desc, DPL 3
and also dump the segment registers for the kernel module:
CS = 10H
DS = 00H
ES = 00H
SS = 00H
FS = 00H
GS = 00H
Q1: Does kernel module not use DS and SS?
On the other side, I wrote a ring 3 application, also dump the segment registers in main():
CS = 33H
DS = 00H
ES = 00H
SS = 2BH
FS = 00H
GS = 00H
Q2: The app's CS points to 64-bit code desc in GDT, SS points to DATA desc in GDT. That's no problem, but why the app's DS is also 00H?
I don't think gcc can compile all the code without using DS or SS.
64-bit mode (aka long mode) does not use segmentation, so any null selector (i.e. 00H
) will work for data segments (all but CS). The code segment is still necessary for selecting 64-bit mode vs 32-bit (compatibility) mode, but the offset
and length
parts of the selector are not used.
So, in a sense, DS and SS are still being "used" (because it's more-or-less impossible to avoid them), but not from the GDT.