My kernel cannot response interrupt from APIC and I don't know where the error occurs

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
TYDQSoft
Posts: 18
Joined: Sun Mar 17, 2024 9:11 am
Libera.chat IRC: TYDQSoft

My kernel cannot response interrupt from APIC and I don't know where the error occurs

Post by TYDQSoft »

My total problematic kernel is on https://github.com/TYDQSoft/UEFIPascalOS
I was confused when I trying to execute my kernel in UEFI and faced the problem as the title,which remain my problem unknown.
The screen should be renewed once,However,the Virtual Machine testing result indicate that the screen will not to be renewed.
Does My kernel have some error in idt and gdt or my APIC request got error?
My kernel main code is:

Code: Select all

procedure kernel_main;[public,alias:'kernel_main'];
var ptr1,ptr2,ptr3,ptr4:Pointer;
    request:acpi_request;
begin
 ptr4:=graph_heap_allocmem(gheap.screen_width,gheap.screen_height,1,1,true);
 ptr1:=graph_heap_allocmem(640,480,1,1,true);
 ptr2:=graph_heap_allocmem(960,720,641,481,true);
 ptr3:=graph_heap_allocmem(640,480,1281,961,true);
 graph_heap_draw_block(ptr4,1,1,gheap.screen_width,gheap.screen_height,graph_color_red);
 graph_heap_draw_eclipse(ptr1,1,1,240,360,graph_color_yellow);
 graph_heap_draw_fanshape(ptr2,480,360,300,60,120,graph_color_green);
 graph_heap_draw_block(ptr3,200,1,240,480,graph_color_blue);
 graph_heap_output_screen;
 kernel_handle_function_init(@kernel_timer);
 kernel_handle_function_add_param(Pointer(ptr1));
 request.requestrootclass:=acpi_request_x86_local_apic;
 request.requestsubclass:=acpi_request_x86_local_apic_timer;
 request.requestAPICIndex:=1;
 request.requestTimer:=10;
 request.requestTimerStatus:=0;
 request.requestNumber:=33;
 acpi_cpu_request_interrupt(os_cpuinfo,request);
 while True do;
 graph_heap_freemem(ptr2);
 graph_heap_freemem(ptr1);
 graph_heap_freemem(ptr4);
 graph_heap_freemem(ptr3); 
end;
Octocontrabass
Member
Member
Posts: 5754
Joined: Mon Mar 25, 2013 7:01 pm

Re: My kernel cannot response interrupt from APIC and I don't know where the error occurs

Post by Octocontrabass »

What kind of debugging have you tried so far? QEMU can log interrupts (with "-d int"), and the QEMU monitor can show you the APIC state (with "info pic").
TYDQSoft
Posts: 18
Joined: Sun Mar 17, 2024 9:11 am
Libera.chat IRC: TYDQSoft

Re: My kernel cannot response interrupt from APIC and I don't know where the error occurs

Post by TYDQSoft »

Octocontrabass wrote: Sun Apr 13, 2025 4:18 pm What kind of debugging have you tried so far? QEMU can log interrupts (with "-d int"), and the QEMU monitor can show you the APIC state (with "info pic").
OK.I just using the UEFI Internal Debugger in ovmf.Maybe QEMU Debugger can be more useful,thanks.
However,when I directly use int $20(Hexdecimal number)(This interrupt was self-defined),My bare metal crashes and reboot continuously.WHY?
Octocontrabass
Member
Member
Posts: 5754
Joined: Mon Mar 25, 2013 7:01 pm

Re: My kernel cannot response interrupt from APIC and I don't know where the error occurs

Post by Octocontrabass »

TYDQSoft wrote: Sun Apr 13, 2025 10:57 pmWHY?
QEMU's interrupt log will help us figure out why.
TYDQSoft
Posts: 18
Joined: Sun Mar 17, 2024 9:11 am
Libera.chat IRC: TYDQSoft

Re: My kernel cannot response interrupt from APIC and I don't know where the error occurs

Post by TYDQSoft »

Octocontrabass wrote: Sun Apr 13, 2025 11:15 pm
TYDQSoft wrote: Sun Apr 13, 2025 10:57 pmWHY?
QEMU's interrupt log will help us figure out why.
I will try this as your advice told me that.
TYDQSoft
Posts: 18
Joined: Sun Mar 17, 2024 9:11 am
Libera.chat IRC: TYDQSoft

Re: My kernel cannot response interrupt from APIC and I don't know where the error occurs

Post by TYDQSoft »

Octocontrabass wrote: Sun Apr 13, 2025 11:15 pm
TYDQSoft wrote: Sun Apr 13, 2025 10:57 pmWHY?
QEMU's interrupt log will help us figure out why.
According to QEMU,How to understand the QEMU -d int information return like that:

Code: Select all

Servicing hardware INT=0x20
  1548: v=20 e=0000 i=0 cpl=0 IP=0038:00000000bed08431 pc=00000000bed08431 SP=0030:00000000bfe80458 env->regs[R_EAX]=0000000000000000
And My info pic command in QEMU monitor return that:

Code: Select all

ioapic0: ver=0x20 id=0x00 sel=0x00
  pin 0  0x0000000000010000 dest=0 vec=0   active-hi edge  masked fixed  physical
  pin 1  0x0000000000010000 dest=0 vec=0   active-hi edge  masked fixed  physical
  pin 2  0x0000000000010000 dest=0 vec=0   active-hi edge  masked fixed  physical
  pin 3  0x0000000000010000 dest=0 vec=0   active-hi edge  masked fixed  physical
  pin 4  0x0000000000010000 dest=0 vec=0   active-hi edge  masked fixed  physical
  pin 5  0x0000000000010000 dest=0 vec=0   active-hi edge  masked fixed  physical
  pin 6  0x0000000000010000 dest=0 vec=0   active-hi edge  masked fixed  physical
  pin 7  0x0000000000010000 dest=0 vec=0   active-hi edge  masked fixed  physical
  pin 8  0x0000000000010000 dest=0 vec=0   active-hi edge  masked fixed  physical
  pin 9  0x0000000000010000 dest=0 vec=0   active-hi edge  masked fixed  physical
  pin 10 0x0000000000010000 dest=0 vec=0   active-hi edge  masked fixed  physical
  pin 11 0x0000000000010000 dest=0 vec=0   active-hi edge  masked fixed  physical
  pin 12 0x0000000000010000 dest=0 vec=0   active-hi edge  masked fixed  physical
  pin 13 0x0000000000010000 dest=0 vec=0   active-hi edge  masked fixed  physical
  pin 14 0x0000000000010000 dest=0 vec=0   active-hi edge  masked fixed  physical
  pin 15 0x0000000000010000 dest=0 vec=0   active-hi edge  masked fixed  physical
  pin 16 0x0000000000010000 dest=0 vec=0   active-hi edge  masked fixed  physical
  pin 17 0x0000000000010000 dest=0 vec=0   active-hi edge  masked fixed  physical
  pin 18 0x0000000000010000 dest=0 vec=0   active-hi edge  masked fixed  physical
  pin 19 0x0000000000010000 dest=0 vec=0   active-hi edge  masked fixed  physical
  pin 20 0x0000000000010000 dest=0 vec=0   active-hi edge  masked fixed  physical
  pin 21 0x0000000000010000 dest=0 vec=0   active-hi edge  masked fixed  physical
  pin 22 0x0000000000010000 dest=0 vec=0   active-hi edge  masked fixed  physical
  pin 23 0x0000000000010000 dest=0 vec=0   active-hi edge  masked fixed  physical
  IRR      (none)
  Remote IRR (none)
pic1: irr=00 imr=ff isr=00 hprio=0 irq_base=00 rr_sel=0 elcr=00 fnm=0
pic0: irr=01 imr=ff isr=00 hprio=0 irq_base=00 rr_sel=0 elcr=00 fnm=0
Do you know how to make sense of these information from info pic?
Octocontrabass
Member
Member
Posts: 5754
Joined: Mon Mar 25, 2013 7:01 pm

Re: My kernel cannot response interrupt from APIC and I don't know where the error occurs

Post by Octocontrabass »

TYDQSoft wrote: Mon Apr 14, 2025 3:46 amHow to understand the QEMU -d int information return like that:
  • "1548:" - There have been 1548 interrupts before this one
  • "v=20" - This interrupt uses vector 0x20
  • "e=0000" - If this interrupt was caused by an exception that has an error code, the error code is 0x0000
  • "i=0" - The source of this interrupt was not internal to the CPU
Usually the interesting part is the last few interrupts before the reboot. You can stop QEMU from rebooting by adding "-no-reboot" to your QEMU command line. (You might also need "-no-shutdown" to keep QEMU open.)
TYDQSoft wrote: Mon Apr 14, 2025 3:46 amDo you know how to make sense of these information from info pic?
  • "ioapic0:" - The following information describes the state of the first IOAPIC
  • "ver=0x20" - The IOAPIC version is 0x20
  • "id=0x00" - The ID currently assigned to this IOAPIC is 0
  • "sel=0x00" - The window register is currently pointed at index 0 (the ID register)
  • "pin 0" - The following information describes the redirection table register for pin 0 on this IOAPIC
  • "0x0000000000010000" - This is the raw value of the redirection table register
  • "dest=0 vec=0 active-hi edge masked fixed physical" - This is all the fields of that redirection table register decoded for your convenience
  • "IRR (none)" - There are no interrupts waiting to be serviced by this IOAPIC
  • "Remote IRR (none)" - There are no level-triggered interrupts waiting for EOI in this IOAPIC
  • "pic1:" - The rest of this line describes the state of the secondary legacy PIC
  • "pic0:" - The rest of this line describes the state of the primary legacy PIC
From this output, it looks like none of the interrupt controllers have been initialized yet. Try halting QEMU at a point after you've initialized the interrupt controllers if you want to see whether or not you initialized them correctly.
TYDQSoft
Posts: 18
Joined: Sun Mar 17, 2024 9:11 am
Libera.chat IRC: TYDQSoft

Re: My kernel cannot response interrupt from APIC and I don't know where the error occurs

Post by TYDQSoft »

Octocontrabass wrote: Mon Apr 14, 2025 10:44 am
TYDQSoft wrote: Mon Apr 14, 2025 3:46 amHow to understand the QEMU -d int information return like that:
  • "1548:" - There have been 1548 interrupts before this one
  • "v=20" - This interrupt uses vector 0x20
  • "e=0000" - If this interrupt was caused by an exception that has an error code, the error code is 0x0000
  • "i=0" - The source of this interrupt was not internal to the CPU
Usually the interesting part is the last few interrupts before the reboot. You can stop QEMU from rebooting by adding "-no-reboot" to your QEMU command line. (You might also need "-no-shutdown" to keep QEMU open.)
TYDQSoft wrote: Mon Apr 14, 2025 3:46 amDo you know how to make sense of these information from info pic?
  • "ioapic0:" - The following information describes the state of the first IOAPIC
  • "ver=0x20" - The IOAPIC version is 0x20
  • "id=0x00" - The ID currently assigned to this IOAPIC is 0
  • "sel=0x00" - The window register is currently pointed at index 0 (the ID register)
  • "pin 0" - The following information describes the redirection table register for pin 0 on this IOAPIC
  • "0x0000000000010000" - This is the raw value of the redirection table register
  • "dest=0 vec=0 active-hi edge masked fixed physical" - This is all the fields of that redirection table register decoded for your convenience
  • "IRR (none)" - There are no interrupts waiting to be serviced by this IOAPIC
  • "Remote IRR (none)" - There are no level-triggered interrupts waiting for EOI in this IOAPIC
  • "pic1:" - The rest of this line describes the state of the secondary legacy PIC
  • "pic0:" - The rest of this line describes the state of the primary legacy PIC
From this output, it looks like none of the interrupt controllers have been initialized yet. Try halting QEMU at a point after you've initialized the interrupt controllers if you want to see whether or not you initialized them correctly.
OK,without YOU,I cannot make sense of these log from QEMU.
TYDQSoft
Posts: 18
Joined: Sun Mar 17, 2024 9:11 am
Libera.chat IRC: TYDQSoft

Re: My kernel cannot response interrupt from APIC and I don't know where the error occurs

Post by TYDQSoft »

I got an error when calling interrupt like this:

Code: Select all

Servicing hardware INT=0x20
   608: v=20 e=0000 i=0 cpl=0 IP=0038:00000000becf8266 pc=00000000becf8266 SP=0030:00000000bfe7fd48 env->regs[R_EAX]=00000000bed0dac0
RAX=00000000bed0dac0 RBX=0000000000000010 RCX=00000000bed0dac0 RDX=abd7f02e4201db00
RSI=00000000be917000 RDI=0000000000000001 RBP=00000000bfe7fd80 RSP=00000000bfe7fd48
R8 =00000000be917000 R9 =00000000be917fff R10=00000000be917258 R11=00000000be917258
R12=000000000000001f R13=0000000000000007 R14=000000000002600f R15=00000000be917fff
RIP=00000000becf8266 RFL=00000206 [-----P-] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0030 0000000000000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
CS =0038 0000000000000000 ffffffff 00af9a00 DPL=0 CS64 [-R-]
SS =0030 0000000000000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
DS =0030 0000000000000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
FS =0030 0000000000000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
GS =0030 0000000000000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
LDT=0000 0000000000000000 0000ffff 00008200 DPL=0 LDT
TR =0000 0000000000000000 0000ffff 00008b00 DPL=0 TSS64-busy
GDT=     00000000bf5dc000 00000047
IDT=     00000000bf144018 00000fff
CR0=80010033 CR2=0000000000000000 CR3=00000000bf801000 CR4=00000668
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000 
DR6=00000000ffff0ff0 DR7=0000000000000400
CCS=0000000000000020 CCD=00000000bfe7fd50 CCO=SUBQ
EFER=0000000000000d00
   609: v=14 e=0000 i=1 cpl=0 IP=0038:00000000be1902c9 pc=00000000be1902c9 SP=0030:00000000bfe801d0 env->regs[R_EAX]=0000000000000020
RAX=0000000000000020 RBX=0000000000000000 RCX=00000000fee00000 RDX=00000000fee00000
RSI=00000000bfe801d0 RDI=00000000be19b6c0 RBP=00000000bfe803f0 RSP=00000000bfe801d0
R8 =00000000000001e0 R9 =00000000ffff0000 R10=00000000be917258 R11=0000000000000000
R12=0000000000000000 R13=0000000000000000 R14=00000000be19d018 R15=00000000be830318
RIP=00000000be1902c9 RFL=00000202 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0030 0000000000000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
CS =0038 0000000000000000 ffffffff 00af9a00 DPL=0 CS64 [-R-]
SS =0030 0000000000000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
DS =0030 0000000000000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
FS =0030 0000000000000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
GS =0030 0000000000000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
LDT=0000 0000000000000000 0000ffff 00008200 DPL=0 LDT
TR =0000 0000000000000000 0000ffff 00008b00 DPL=0 TSS64-busy
GDT=     03f000000000be19 0000b7c0
IDT=     b7c000000000be19 0000b81c
CR0=80010033 CR2=0000000000000000 CR3=00000000bf801000 CR4=00000668
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000 
DR6=00000000ffff0ff0 DR7=0000000000000400
CCS=0000000000000001 CCD=0000000000000020 CCO=SUBL
EFER=0000000000000d00
check_exception old: 0xffffffff new 0xd
   610: v=0d e=0000 i=0 cpl=0 IP=0038:00000000be1902c9 pc=00000000be1902c9 SP=0030:00000000bfe801d0 env->regs[R_EAX]=0000000000000020
RAX=0000000000000020 RBX=0000000000000000 RCX=00000000fee00000 RDX=00000000fee00000
RSI=00000000bfe801d0 RDI=00000000be19b6c0 RBP=00000000bfe803f0 RSP=00000000bfe801d0
R8 =00000000000001e0 R9 =00000000ffff0000 R10=00000000be917258 R11=0000000000000000
R12=0000000000000000 R13=0000000000000000 R14=00000000be19d018 R15=00000000be830318
RIP=00000000be1902c9 RFL=00000202 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0030 0000000000000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
CS =0038 0000000000000000 ffffffff 00af9a00 DPL=0 CS64 [-R-]
SS =0030 0000000000000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
DS =0030 0000000000000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
FS =0030 0000000000000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
GS =0030 0000000000000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
LDT=0000 0000000000000000 0000ffff 00008200 DPL=0 LDT
TR =0000 0000000000000000 0000ffff 00008b00 DPL=0 TSS64-busy
GDT=     03f000000000be19 0000b7c0
IDT=     b7c000000000be19 0000b81c
CR0=80010033 CR2=b7c000000000bf59 CR3=00000000bf801000 CR4=00000668
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000 
DR6=00000000ffff0ff0 DR7=0000000000000400
CCS=0000000000000001 CCD=0000000000000020 CCO=SUBL
EFER=0000000000000d00
check_exception old: 0xd new 0xd
   611: v=08 e=0000 i=0 cpl=0 IP=0038:00000000be1902c9 pc=00000000be1902c9 SP=0030:00000000bfe801d0 env->regs[R_EAX]=0000000000000020
RAX=0000000000000020 RBX=0000000000000000 RCX=00000000fee00000 RDX=00000000fee00000
RSI=00000000bfe801d0 RDI=00000000be19b6c0 RBP=00000000bfe803f0 RSP=00000000bfe801d0
R8 =00000000000001e0 R9 =00000000ffff0000 R10=00000000be917258 R11=0000000000000000
R12=0000000000000000 R13=0000000000000000 R14=00000000be19d018 R15=00000000be830318
RIP=00000000be1902c9 RFL=00000202 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0030 0000000000000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
CS =0038 0000000000000000 ffffffff 00af9a00 DPL=0 CS64 [-R-]
SS =0030 0000000000000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
DS =0030 0000000000000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
FS =0030 0000000000000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
GS =0030 0000000000000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
LDT=0000 0000000000000000 0000ffff 00008200 DPL=0 LDT
TR =0000 0000000000000000 0000ffff 00008b00 DPL=0 TSS64-busy
GDT=     03f000000000be19 0000b7c0
IDT=     b7c000000000be19 0000b81c
CR0=80010033 CR2=b7c000000000bee9 CR3=00000000bf801000 CR4=00000668
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000 
DR6=00000000ffff0ff0 DR7=0000000000000400
CCS=0000000000000001 CCD=0000000000000020 CCO=SUBL
EFER=0000000000000d00
check_exception old: 0x8 new 0xd
WHY my gdt base address and idt base address and their size is wrong,the related code is:

Code: Select all

procedure kernel_gdt_set_entry(index:word;Base:qword;Limit:dword;AccessByte:byte;Flags:byte);
begin
 PByte(@gdtentry[index].AccessByte)^:=AccessByte;
 gdtentry[index].baselow:=base and $FFFF;
 gdtentry[index].basemid:=(base shr 16) and $FF;
 gdtentry[index].Basehigh1:=(base shr 24) and $FF;
 gdtentry[index].Basehigh2:=(base shr 32) and $FFFFFFFF;
 gdtentry[index].Flags:=Flags;
 gdtentry[index].limitlow:=Limit and $FFFF;
 gdtentry[index].Limithigh:=(Limit shr 16) and $F;
 gdtentry[index].Reserved:=0;
end;
procedure kernel_idt_set_entry(index:word;address:qword;GateType:byte;PrivilegeLevel:byte);
begin
 idtentry[index].DescriptorPrivilegeLevel:=PrivilegeLevel;
 idtentry[index].Present:=1;
 idtentry[index].SegmentSelector.Index:=1;
 idtentry[index].SegmentSelector.TableIndicator:=0;
 idtentry[index].SegmentSelector.RequestPrivilegeLevel:=0;
 idtentry[index].GateType:=GateType;
 idtentry[index].offsetlow:=address and $FFFF;
 idtentry[index].offsetmiddle:=(address shr 16) and $FFFF;
 idtentry[index].offsethigh:=(address shr 32) and $FFFFFFFF;
 idtentry[index].Reserved1:=0;
 idtentry[index].Reserved2:=0;
 idtentry[index].Reserved3:=0;
 idtentry[index].IST:=0;
 if(address=0) then idtentry[index].Present:=0 else idtentry[index].Present:=1;
end;
procedure kernel_gdt_initialize;
var tempptr:Px64_gdt_descriptor;
begin
 gdt.Offset:=Qword(@gdtentry);
 gdt.Size:=sizeof(gdtentry)-1;
 kernel_gdt_set_entry(1,0,0,$0,$0);
 kernel_gdt_set_entry(2,0,$FFFFF,$9A,$A);
 kernel_gdt_set_entry(3,0,$FFFFF,$92,$C);
 kernel_gdt_set_entry(4,0,$FFFFF,$FA,$A);
 kernel_gdt_set_entry(5,0,$FFFFF,$F2,$C);
 tempptr:=@gdt;
 asm
  lgdt tempptr
 end;
end;
procedure kernel_idt_initialize;
var i:word;
    tempptr:Px64_idt_descriptor;
begin
 idt.Offset:=Qword(@idtentry);
 idt.Size:=sizeof(idtentry)-1;
 i:=1;
 while(i<=256)do
  begin
   case i of
   1:kernel_idt_set_entry(i,Qword(@kernel_idt_handler_division_by_zero),$E,0);
   2:kernel_idt_set_entry(i,Qword(@kernel_idt_handler_Debug_exception),$F,0);
   3:kernel_idt_set_entry(i,Qword(@kernel_idt_handler_NMI_interrupt),$E,0);
   4:kernel_idt_set_entry(i,Qword(@kernel_idt_handler_breakpoint),$F,0);
   5:kernel_idt_set_entry(i,Qword(@kernel_idt_handler_overflow),$F,0);
   6:kernel_idt_set_entry(i,Qword(@kernel_idt_handler_Bound_Range_exceed),$E,0);
   7:kernel_idt_set_entry(i,Qword(@kernel_idt_handler_Invaild_Opcode),$E,0);
   8:kernel_idt_set_entry(i,Qword(@kernel_idt_handler_Device_Not_Available),$E,0);
   9:kernel_idt_set_entry(i,Qword(@kernel_idt_handler_Double_Fault),$E,0);
   10:kernel_idt_set_entry(i,Qword(@kernel_idt_handler_Coprocessor_Segment_overrun),$E,0);
   11:kernel_idt_set_entry(i,Qword(@kernel_idt_handler_invaild_TSS),$E,0);
   12:kernel_idt_set_entry(i,Qword(@kernel_idt_handler_Segment_Not_Present),$E,0);
   13:kernel_idt_set_entry(i,Qword(@kernel_idt_handler_Stack_Segment_Fault),$E,0);
   14:kernel_idt_set_entry(i,Qword(@kernel_idt_handler_General_Protection),$E,0);
   15:kernel_idt_set_entry(i,Qword(@kernel_idt_handler_Page_Fault),$E,0);
   16:kernel_idt_set_entry(i,0,$E,0);
   17:kernel_idt_set_entry(i,Qword(@kernel_idt_handler_FPU_Math_Error),$E,0);
   18:kernel_idt_set_entry(i,Qword(@kernel_idt_handler_Alignment_Check),$E,0);
   19:kernel_idt_set_entry(i,Qword(@kernel_idt_handler_Machine_Check),$E,0);
   20:kernel_idt_set_entry(i,Qword(@kernel_idt_handler_SIMD_Floating_Point),$E,0);
   21:kernel_idt_set_entry(i,Qword(@kernel_idt_handler_Virtualization_Exception),$E,0);
   22..32:kernel_idt_set_entry(i,Qword(@kernel_idt_handler_empty),$E,0);
   33:kernel_idt_set_entry(i,Qword(@kernel_idt_handler_timer),$E,3);
   34..256:kernel_idt_set_entry(i,Qword(@kernel_idt_handler_empty),$E,0);
   end;
   inc(i);
  end;
 tempptr:=@idt;
 asm
  lidt tempptr
 end;
end;
{$ENDIF}
procedure kernel_initialize;
var arch:byte;
begin
 arch:=kernel_get_architecture;
 case arch of
 0,1,2:
 begin
  {$IF Defined(cpui386) or Defined(cpux86_64) or Defined(cpuia64)}
  asm
   cli
  end;
  kernel_gdt_initialize;
  kernel_idt_initialize;
  asm
   sti
  end;
  {$ENDIF}
 end;
 end;
end;

Code: Select all

var gdt:x64_gdt_descriptor;
    gdtentry:array[1..5] of x64_gdt_descriptor_gate;
    idt:x64_idt_descriptor;
    idtentry:array[1..256] of x64_idt_descriptor_gate;

Code: Select all

type x86_gdt_descriptor=packed record
                        Size:word;
                        Offset:dword;
                        end;
     Px86_gdt_descriptor=^x86_gdt_descriptor;
     x64_gdt_descriptor=packed record
                        Size:word;
                        Offset:qword;
                        end;
     Px64_gdt_descriptor=^x64_gdt_descriptor;
     ia_gdt_access_byte_normal=bitpacked record
                               Accessed:0..1;
                               EnableReadOrWrite:0..1;
                               EnableDirectionOrConfirming:0..1;
                               Executable:0..1;
                               DescriptorType:0..1;
                               DescriptorPrivilageLevel:0..3;
                               Present:0..1;
                               end;
     ia_gdt_access_byte_special=bitpacked record
                                GDTType:0..15;
                                DescriptorType:0..1;
                                DescriptorPrivilageLevel:0..3;
                                Present:0..1;
                                end;
     ia_gdt_access_byte=packed record
                        case Boolean of
                        True:(accessbytenormal:ia_gdt_access_byte_normal;);
                        False:(accessbytespecial:ia_gdt_access_byte_special;);
                        end;
     x86_gdt_descriptor_gate=bitpacked record
                             limitlow:word;
                             baselow:word;
                             basemid:byte;
                             AccessByte:ia_gdt_access_byte;
                             Limithigh:0..15;
                             Flags:0..15;
                             Basehigh:byte;
                             end;
     Px86_gdt_descriptor_gate=^x86_gdt_descriptor_gate;
     x64_gdt_descriptor_gate=bitpacked record
                             limitlow:word;
                             baselow:word;
                             basemid:byte;
                             AccessByte:ia_gdt_access_byte;
                             Limithigh:0..15;
                             Flags:0..15;
                             Basehigh1:byte;
                             Basehigh2:dword;
                             Reserved:dword;
                             end;
     Px64_gdt_descriptor_gate=^x64_gdt_descriptor_gate;
     x86_idt_descriptor=packed record
                        Size:word;
                        Offset:dword;
                        end;
     Px86_idt_descriptor=^x86_idt_descriptor;
     x64_idt_descriptor=packed record
                        Size:word;
                        Offset:qword;
                        end;
     Px64_idt_descriptor=^x64_idt_descriptor;
     ia_segment_descriptor=bitpacked record
                           RequestPrivilegeLevel:0..3;
                           TableIndicator:0..1;
                           Index:0..8191;
                           end;
     x86_idt_descriptor_gate=bitpacked record
                             offsetlow:word;
                             SegmentSelector:ia_segment_descriptor;
                             Reserved1:byte;
                             GateType:0..15;
                             Reserved2:0..1;
                             DescriptorPrivilegeLevel:0..3;
                             Present:0..1;
                             offsethigh:word;
                             end;
     Px86_idt_descriptor_gate=^x86_idt_descriptor_gate;
     x64_idt_descriptor_gate=bitpacked record
                             offsetlow:word;
                             SegmentSelector:ia_segment_descriptor;
                             IST:0..7;
                             Reserved1:0..31;
                             GateType:0..15;
                             Reserved2:0..1;
                             DescriptorPrivilegeLevel:0..3;
                             Present:0..1;
                             offsetmiddle:word;
                             offsethigh:dword;
                             Reserved3:dword;
                             end;
     Px64_idt_descriptor_gate=^x64_idt_descriptor_gate;
Does it has error in my source code?
Octocontrabass
Member
Member
Posts: 5754
Joined: Mon Mar 25, 2013 7:01 pm

Re: My kernel cannot response interrupt from APIC and I don't know where the error occurs

Post by Octocontrabass »

TYDQSoft wrote: Mon Apr 14, 2025 7:07 pmWHY my gdt base address and idt base address and their size is wrong
Either the data structures you're using are wrong or the pointers you're passing to the LGDT and LIDT instructions are wrong.

Unfortunately, I can't read Pascal, so I can't tell you if the problem is somewhere in the code you've posted. You'll have to use a debugger.
Post Reply