The source code may have a problem when the IDT is initialized. 
This code is located in `src/cpu/x86/16bit/entry16.inc`.
----------------------------------------------------------------------------------------------
movw %cs, %ax
shlw $4, %ax
movw $nullidt_offset, %bx
subw %ax, %bx
lidt         %cs:(%bx)     —> this  mybe lidtl
movw $gdtptr16_offset, %bx
subw %ax, %bx
lgdtl         %cs:(%bx)
---------------------------------------------------------------------------------------------- 
lidt only used for base 0-16M. 
But nullidt located in (4G-64k) - 4G space.
This instruct must be **lidtl**

Description of LIDT

IF Instruction is LIDT
    THEN
         IF OperandSize = 16
              THEN
                    IDTR(Limit) ← SRC[0:15];
                    IDTR(Base) ← SRC[16:47] AND 00FFFFFFH;
              ELSE IF 32-bit Operand Size
                    THEN
                         IDTR(Limit) ← SRC[0:15];
                         IDTR(Base) ← SRC[16:47];
                    FI;
              ELSE IF 64-bit Operand Size (* In 64-Bit Mode *)
                    THEN
                         IDTR(Limit) ← SRC[0:15];
                         IDTR(Base) ← SRC[16:79];
                    FI;
         FI;
    ELSE (* Instruction is LGDT *)
         IF OperandSize = 16
              THEN
                    GDTR(Limit) ← SRC[0:15];
                    GDTR(Base) ← SRC[16:47] AND 00FFFFFFH;
              ELSE IF 32-bit Operand Size
                    THEN
                         GDTR(Limit) ← SRC[0:15];
                         GDTR(Base) ← SRC[16:47];
                    FI;
              ELSE IF 64-bit Operand Size (* In 64-Bit Mode *)
                    THEN
                         GDTR(Limit) ← SRC[0:15];
                         GDTR(Base) ← SRC[16:79];
                    FI;
         FI;
FI;





------------------

王翔

安全研究员

广州市腾御安信息科技有限公司

广州市天河区珠江新城华穗路406号保利克洛维二期中景A座1020-1024