Page 2 of 2

Re: Global Descriptor Table Issues

Posted: Thu Feb 11, 2010 3:22 pm
by visuramanan
Hi,

I am having the exact same problem.. And i'm stuck here for a week.. my bochs output is the same as yours.. is there a solution for this?? I m following bran's kernel development tutorial..

Any help would be greatly appreciated..

Vishwa

Re: Global Descriptor Table Issues

Posted: Sat Feb 13, 2010 11:52 am
by mitikoro
Is the struct gdt_entry correct? I would change it to:

Code: Select all

struct gdt_entry {
   unsigned short low_limit;
   unsigned short low_base;
   unsigned char middle_base;
   unsigned char access;
   unsigned char gran;
   unsigned char high_base;
}__attribute__((packed));

Re: Global Descriptor Table Issues

Posted: Sun Feb 14, 2010 6:13 pm
by visuramanan
Thank you so much.. the order of entries in the struct gdt_entry was wrong for me.. thats why it was triple faulting.. thank u :)

Re: Global Descriptor Table Issues

Posted: Mon Dec 30, 2013 1:10 pm
by ApproximateIdentity
I am also following JamesM's tutorial and I have been having similar issues and have spent a week trying to solve it without success.

I believe I am setting up the gdt and the idt successfully, but something is clearly going wrong. What I do is initialize the gdt/idt, then I initialize a vga terminal, and then finally I try to test the interrupts by issuing 'asm volatile("int $0x1")' and then ''asm volatile("int $0x2")'. The first interrupt seems to work fine, but after that I start getting a lot of int 13 interrupts with error code 3416 (the second 'asm volatile("int $0x2")' never seems to be issued). It seems that I'm getting a bunch of general protection faults. After looking at the bochsout.txt file, it seems like the problem is related to this message: "fetch_raw_descriptor: GDT: index (d5f) 1ab > limit (27)". I'm not sure what to make of it...

Here is my bochsout.txt file:

Code: Select all

00000000000i[     ] Bochs x86 Emulator 2.6.2.svn
00000000000i[     ]   Built from SVN snapshot after release 2.6.2
00000000000i[     ] Compiled on Dec 28 2013 at 17:08:32
00000000000i[     ] System configuration
00000000000i[     ]   processors: 1 (cores=1, HT threads=1)
00000000000i[     ]   A20 line support: yes
00000000000i[     ] IPS is set to 1000000
00000000000i[     ] CPU configuration
00000000000i[     ]   SMP support: no
00000000000i[     ]   level: 6
00000000000i[     ]   APIC support: xapic
00000000000i[     ]   FPU support: yes
00000000000i[     ]   MMX support: yes
00000000000i[     ]   3dnow! support: no
00000000000i[     ]   SEP support: yes
00000000000i[     ]   SIMD support: sse2
00000000000i[     ]   XSAVE support: no 
00000000000i[     ]   AES support: no
00000000000i[     ]   SHA support: no
00000000000i[     ]   MOVBE support: no
00000000000i[     ]   ADX support: no
00000000000i[     ]   x86-64 support: no
00000000000i[     ]   MWAIT support: yes
00000000000i[     ] Optimization configuration
00000000000i[     ]   RepeatSpeedups support: no
00000000000i[     ]   Fast function calls: no
00000000000i[     ]   Handlers Chaining speedups: no
00000000000i[     ] Devices configuration
00000000000i[     ]   NE2000 support: no
00000000000i[     ]   PCI support: yes, enabled=yes
00000000000i[     ]   SB16 support: no
00000000000i[     ]   USB support: no
00000000000i[     ]   VGA extension support: vbe
00000000000i[MEM0 ] allocated memory at 0xb3652008. after alignment, vector=0xb3653000
00000000000i[MEM0 ] 32.00MB
00000000000i[MEM0 ] mem block size = 0x00100000, blocks=32
00000000000i[MEM0 ] rom at 0xfffe0000/131072 ('/usr/share/bochs/BIOS-bochs-latest')
00000000000i[VTIME] using 'realtime pit' synchronization method
00000000000i[     ] init_dev of 'pci' plugin device by virtual method
00000000000i[DEV  ] i440FX PMC present at device 0, function 0
00000000000i[     ] init_dev of 'pci2isa' plugin device by virtual method
00000000000i[DEV  ] PIIX3 PCI-to-ISA bridge present at device 1, function 0
00000000000i[     ] init_dev of 'cmos' plugin device by virtual method
00000000000i[CMOS ] Using local time for initial clock
00000000000i[CMOS ] Setting initial clock to: Mon Dec 30 10:51:42 2013 (time0=1388429502)
00000000000i[     ] init_dev of 'dma' plugin device by virtual method
00000000000i[DMA  ] channel 4 used by cascade
00000000000i[     ] init_dev of 'pic' plugin device by virtual method
00000000000i[     ] init_dev of 'pit' plugin device by virtual method
00000000000i[     ] init_dev of 'floppy' plugin device by virtual method
00000000000i[DMA  ] channel 2 used by Floppy Drive
00000000000i[     ] init_dev of 'vga' plugin device by virtual method
00000000000i[MEM0 ] Register memory access handlers: 0x0000000a0000 - 0x0000000bffff
00000000000i[VGA  ] interval=200000
00000000000i[MEM0 ] Register memory access handlers: 0x0000e0000000 - 0x0000e0ffffff
00000000000i[BXVGA] VBE Bochs Display Extension Enabled
00000000000i[MEM0 ] rom at 0xc0000/41472 ('/usr/share/bochs/VGABIOS-lgpl-latest')
00000000000i[     ] init_dev of 'acpi' plugin device by virtual method
00000000000i[DEV  ] ACPI Controller present at device 1, function 3
00000000000i[     ] init_dev of 'ioapic' plugin device by virtual method
00000000000i[IOAP ] initializing I/O APIC
00000000000i[MEM0 ] Register memory access handlers: 0x0000fec00000 - 0x0000fec00fff
00000000000i[IOAP ] IOAPIC enabled (base address = 0xfec00000)
00000000000i[     ] init_dev of 'keyboard' plugin device by virtual method
00000000000i[KBD  ] will paste characters every 400 keyboard ticks
00000000000i[     ] init_dev of 'harddrv' plugin device by virtual method
00000000000i[HD   ] CD on ata1-0: 'myos.iso'
00000000000i[CD1  ] load cdrom with path=myos.iso
00000000000i[CD1  ] Opening image file as a cd.
00000000000i[HD   ] Media present in CD-ROM drive
00000000000i[HD   ] Capacity is 1111 sectors (2.17 MB)
00000000000i[HD   ] Using boot sequence cdrom, none, none
00000000000i[HD   ] Floppy boot signature check is enabled
00000000000i[     ] init_dev of 'pci_ide' plugin device by virtual method
00000000000i[DEV  ] PIIX3 PCI IDE controller present at device 1, function 1
00000000000i[     ] init_dev of 'unmapped' plugin device by virtual method
00000000000i[     ] init_dev of 'biosdev' plugin device by virtual method
00000000000i[     ] init_dev of 'speaker' plugin device by virtual method
00000000000e[SPEAK] Failed to open /dev/console: Permission denied
00000000000e[SPEAK] Deactivating beep on console
00000000000i[     ] init_dev of 'extfpuirq' plugin device by virtual method
00000000000i[     ] init_dev of 'parallel' plugin device by virtual method
00000000000i[PAR  ] parallel port 1 at 0x0378 irq 7
00000000000i[     ] init_dev of 'serial' plugin device by virtual method
00000000000i[SER  ] com1 at 0x03f8 irq 4 (mode: null)
00000000000i[     ] init_dev of 'iodebug' plugin device by virtual method
00000000000i[     ] register state of 'pci' plugin device by virtual method
00000000000i[     ] register state of 'pci2isa' plugin device by virtual method
00000000000i[     ] register state of 'cmos' plugin device by virtual method
00000000000i[     ] register state of 'dma' plugin device by virtual method
00000000000i[     ] register state of 'pic' plugin device by virtual method
00000000000i[     ] register state of 'pit' plugin device by virtual method
00000000000i[     ] register state of 'floppy' plugin device by virtual method
00000000000i[     ] register state of 'vga' plugin device by virtual method
00000000000i[     ] register state of 'unmapped' plugin device by virtual method
00000000000i[     ] register state of 'biosdev' plugin device by virtual method
00000000000i[     ] register state of 'speaker' plugin device by virtual method
00000000000i[     ] register state of 'extfpuirq' plugin device by virtual method
00000000000i[     ] register state of 'parallel' plugin device by virtual method
00000000000i[     ] register state of 'serial' plugin device by virtual method
00000000000i[     ] register state of 'iodebug' plugin device by virtual method
00000000000i[     ] register state of 'acpi' plugin device by virtual method
00000000000i[     ] register state of 'ioapic' plugin device by virtual method
00000000000i[     ] register state of 'keyboard' plugin device by virtual method
00000000000i[     ] register state of 'harddrv' plugin device by virtual method
00000000000i[     ] register state of 'pci_ide' plugin device by virtual method
00000000000i[SYS  ] bx_pc_system_c::Reset(HARDWARE) called
00000000000i[CPU0 ] cpu hardware reset
00000000000i[APIC0] allocate APIC id=0 (MMIO enabled) to 0x0000fee00000
00000000000i[CPU0 ] CPUID[0x00000000]: 00000005 756e6547 6c65746e 49656e69
00000000000i[CPU0 ] CPUID[0x00000001]: 00000633 00010800 00000008 1fcbfbff
00000000000i[CPU0 ] CPUID[0x00000002]: 00410601 00000000 00000000 00000000
00000000000i[CPU0 ] CPUID[0x00000003]: 00000000 00000000 00000000 00000000
00000000000i[CPU0 ] CPUID[0x00000004]: 00000000 00000000 00000000 00000000
00000000000i[CPU0 ] CPUID[0x00000005]: 00000040 00000040 00000003 00000020
00000000000i[CPU0 ] CPUID[0x80000000]: 80000008 00000000 00000000 00000000
00000000000i[CPU0 ] CPUID[0x80000001]: 00000000 00000000 00000000 00000000
00000000000i[CPU0 ] CPUID[0x80000002]: 20202020 20202020 20202020 6e492020
00000000000i[CPU0 ] CPUID[0x80000003]: 286c6574 50202952 69746e65 52286d75
00000000000i[CPU0 ] CPUID[0x80000004]: 20342029 20555043 20202020 00202020
00000000000i[CPU0 ] CPUID[0x80000005]: 01ff01ff 01ff01ff 40020140 40020140
00000000000i[CPU0 ] CPUID[0x80000006]: 00000000 42004200 02008140 00000000
00000000000i[CPU0 ] CPUID[0x80000007]: 00000000 00000000 00000000 00000000
00000000000i[CPU0 ] CPUID[0x80000008]: 00002028 00000000 00000000 00000000
00000000000i[     ] reset of 'pci' plugin device by virtual method
00000000000i[     ] reset of 'pci2isa' plugin device by virtual method
00000000000i[     ] reset of 'cmos' plugin device by virtual method
00000000000i[     ] reset of 'dma' plugin device by virtual method
00000000000i[     ] reset of 'pic' plugin device by virtual method
00000000000i[     ] reset of 'pit' plugin device by virtual method
00000000000i[     ] reset of 'floppy' plugin device by virtual method
00000000000i[     ] reset of 'vga' plugin device by virtual method
00000000000i[     ] reset of 'acpi' plugin device by virtual method
00000000000i[     ] reset of 'ioapic' plugin device by virtual method
00000000000i[     ] reset of 'keyboard' plugin device by virtual method
00000000000i[     ] reset of 'harddrv' plugin device by virtual method
00000000000i[     ] reset of 'pci_ide' plugin device by virtual method
00000000000i[     ] reset of 'unmapped' plugin device by virtual method
00000000000i[     ] reset of 'biosdev' plugin device by virtual method
00000000000i[     ] reset of 'speaker' plugin device by virtual method
00000000000i[     ] reset of 'extfpuirq' plugin device by virtual method
00000000000i[     ] reset of 'parallel' plugin device by virtual method
00000000000i[     ] reset of 'serial' plugin device by virtual method
00000000000i[     ] reset of 'iodebug' plugin device by virtual method
00000000000i[     ] set SIGINT handler to bx_debug_ctrlc_handler
00000003305i[BIOS ] $Revision: 1.257 $ $Date: 2011/01/26 09:52:02 $
00000317046i[KBD  ] reset-disable command received
00000445356i[VBIOS] VGABios $Id: vgabios.c,v 1.75 2011/10/15 14:07:21 vruppert Exp $
00000445427i[BXVGA] VBE known Display Interface b0c0
00000445459i[BXVGA] VBE known Display Interface b0c5
00000448384i[VBIOS] VBE Bios $Id: vbe.c,v 1.64 2011/07/19 18:25:05 vruppert Exp $
00000768499i[BIOS ] Starting rombios32
00000768929i[BIOS ] Shutdown flag 0
00000769512i[BIOS ] ram_size=0x02000000
00000769928i[BIOS ] ram_end=32MB
00000781972i[BIOS ] Found 1 cpu(s)
00000797809i[BIOS ] bios_table_addr: 0x000fb928 end=0x000fcc00
00001125603i[PCI  ] i440FX PMC write to PAM register 59 (TLB Flush)
00001453534i[P2I  ] PCI IRQ routing: PIRQA# set to 0x0b
00001453553i[P2I  ] PCI IRQ routing: PIRQB# set to 0x09
00001453572i[P2I  ] PCI IRQ routing: PIRQC# set to 0x0b
00001453591i[P2I  ] PCI IRQ routing: PIRQD# set to 0x09
00001453601i[P2I  ] write: ELCR2 = 0x0a
00001454361i[BIOS ] PIIX3/PIIX4 init: elcr=00 0a
00001462013i[BIOS ] PCI: bus=0 devfn=0x00: vendor_id=0x8086 device_id=0x1237 class=0x0600
00001464258i[BIOS ] PCI: bus=0 devfn=0x08: vendor_id=0x8086 device_id=0x7000 class=0x0601
00001466342i[BIOS ] PCI: bus=0 devfn=0x09: vendor_id=0x8086 device_id=0x7010 class=0x0101
00001466564i[PIDE ] new BM-DMA address: 0xc000
00001467168i[BIOS ] region 4: 0x0000c000
00001469170i[BIOS ] PCI: bus=0 devfn=0x0b: vendor_id=0x8086 device_id=0x7113 class=0x0680
00001469393i[ACPI ] new irq line = 11
00001469405i[ACPI ] new irq line = 9
00001469434i[ACPI ] new PM base address: 0xb000
00001469448i[ACPI ] new SM base address: 0xb100
00001469476i[PCI  ] setting SMRAM control register to 0x4a
00001633569i[CPU0 ] Enter to System Management Mode
00001633580i[CPU0 ] RSM: Resuming from System Management Mode
00001797602i[PCI  ] setting SMRAM control register to 0x0a
00001806334i[BIOS ] MP table addr=0x000fba00 MPC table addr=0x000fb930 size=0xd0
00001808113i[BIOS ] SMBIOS table addr=0x000fba10
00001811264i[BIOS ] Firmware waking vector 0x1ff00cc
00001816174i[BIOS ] ACPI tables: RSDP addr=0x000fbb30 ACPI DATA addr=0x01ff0000 size=0x1f18
00001816210i[PCI  ] i440FX PMC write to PAM register 59 (TLB Flush)
00001816928i[BIOS ] bios_table_cur_addr: 0x000fbb54
00005699200i[BIOS ] IDE time out
00562453572i[BIOS ] Booting from 07c0:0000
00616235830i[CPU0 ] [616235830] Stopped on MAGIC BREAKPOINT
00616236622e[CPU0 ] fetch_raw_descriptor: GDT: index (d5f) 1ab > limit (27)
00616236637i[CPU0 ] [616236637] Stopped on MAGIC BREAKPOINT
00616237598e[CPU0 ] fetch_raw_descriptor: GDT: index (d5f) 1ab > limit (27)
00616237613i[CPU0 ] [616237613] Stopped on MAGIC BREAKPOINT
00616237613i[     ] dbg: Quit
00616237613i[CPU0 ] CPU is in protected mode (active)
00616237613i[CPU0 ] CS.mode = 32 bit
00616237613i[CPU0 ] SS.mode = 32 bit
00616237613i[CPU0 ] EFER   = 0x00000000
00616237613i[CPU0 ] | EAX=00000010  EBX=00100d58  ECX=00000002  EDX=00000736
00616237613i[CPU0 ] | ESP=001057a8  EBP=00000000  ESI=00000000  EDI=00000000
00616237613i[CPU0 ] | IOPL=0 ID vip vif ac vm rf nt of df if tf sf zf AF pf cf
00616237613i[CPU0 ] | SEG sltr(index|ti|rpl)     base    limit G D
00616237613i[CPU0 ] |  CS:0008( 0001| 0|  0) 00000000 ffffffff 1 1
00616237613i[CPU0 ] |  DS:0010( 0002| 0|  0) 00000000 ffffffff 1 1
00616237613i[CPU0 ] |  SS:0010( 0002| 0|  0) 00000000 ffffffff 1 1
00616237613i[CPU0 ] |  ES:0010( 0002| 0|  0) 00000000 ffffffff 1 1
00616237613i[CPU0 ] |  FS:0010( 0002| 0|  0) 00000000 ffffffff 1 1
00616237613i[CPU0 ] |  GS:0010( 0002| 0|  0) 00000000 ffffffff 1 1
00616237613i[CPU0 ] | EIP=00100b26 (00100b26)
00616237613i[CPU0 ] | CR0=0x60000011 CR2=0x00000000
00616237613i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
00616237613i[CMOS ] Last time is 1388430118 (Mon Dec 30 11:01:58 2013)
00616237613i[CTRL ] quit_sim called with exit code 0
Here is my info gdt output after the second breakpoint above (i.e. after all the problems have started):

Code: Select all

Global Descriptor Table (base=0x00101020, limit=39):
GDT[0x01]=Code segment, base=0x00000000, limit=0xffffffff, Execute/Read, Non-Conforming, Accessed, 32-bit
GDT[0x02]=Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
GDT[0x03]=Code segment, base=0x00000000, limit=0xffffffff, Execute/Read, Non-Conforming, 32-bit
GDT[0x04]=Data segment, base=0x00000000, limit=0xffffffff, Read/Write
Here is my info idt output after the second breakpoint:

Code: Select all

Interrupt Descriptor Table (base=0x00101060, limit=2047):
IDT[0x00]=32-Bit Interrupt Gate target=0x0008:0x00100887, DPL=0
IDT[0x01]=32-Bit Interrupt Gate target=0x0008:0x00100891, DPL=0
IDT[0x02]=32-Bit Interrupt Gate target=0x0008:0x0010089b, DPL=0
IDT[0x03]=32-Bit Interrupt Gate target=0x0008:0x001008a5, DPL=0
IDT[0x04]=32-Bit Interrupt Gate target=0x0008:0x001008af, DPL=0
IDT[0x05]=32-Bit Interrupt Gate target=0x0008:0x001008b9, DPL=0
IDT[0x06]=32-Bit Interrupt Gate target=0x0008:0x001008c3, DPL=0
IDT[0x07]=32-Bit Interrupt Gate target=0x0008:0x001008cd, DPL=0
IDT[0x08]=32-Bit Interrupt Gate target=0x0008:0x001008d7, DPL=0
IDT[0x09]=32-Bit Interrupt Gate target=0x0008:0x001008df, DPL=0
IDT[0x0a]=32-Bit Interrupt Gate target=0x0008:0x001008e9, DPL=0
IDT[0x0b]=32-Bit Interrupt Gate target=0x0008:0x001008f1, DPL=0
IDT[0x0c]=32-Bit Interrupt Gate target=0x0008:0x001008f9, DPL=0
IDT[0x0d]=32-Bit Interrupt Gate target=0x0008:0x00100901, DPL=0
IDT[0x0e]=32-Bit Interrupt Gate target=0x0008:0x00100906, DPL=0
IDT[0x0f]=32-Bit Interrupt Gate target=0x0008:0x0010090b, DPL=0
IDT[0x10]=32-Bit Interrupt Gate target=0x0008:0x00100912, DPL=0
IDT[0x11]=32-Bit Interrupt Gate target=0x0008:0x00100919, DPL=0
IDT[0x12]=32-Bit Interrupt Gate target=0x0008:0x00100920, DPL=0
IDT[0x13]=32-Bit Interrupt Gate target=0x0008:0x00100927, DPL=0
IDT[0x14]=32-Bit Interrupt Gate target=0x0008:0x0010092e, DPL=0
IDT[0x15]=32-Bit Interrupt Gate target=0x0008:0x00100935, DPL=0
IDT[0x16]=32-Bit Interrupt Gate target=0x0008:0x0010093c, DPL=0
IDT[0x17]=32-Bit Interrupt Gate target=0x0008:0x00100943, DPL=0
IDT[0x18]=32-Bit Interrupt Gate target=0x0008:0x0010094a, DPL=0
IDT[0x19]=32-Bit Interrupt Gate target=0x0008:0x00100951, DPL=0
IDT[0x1a]=32-Bit Interrupt Gate target=0x0008:0x00100958, DPL=0
IDT[0x1b]=32-Bit Interrupt Gate target=0x0008:0x0010095f, DPL=0
IDT[0x1c]=32-Bit Interrupt Gate target=0x0008:0x00100966, DPL=0
IDT[0x1d]=32-Bit Interrupt Gate target=0x0008:0x0010096d, DPL=0
IDT[0x1e]=32-Bit Interrupt Gate target=0x0008:0x00100974, DPL=0
IDT[0x1f]=32-Bit Interrupt Gate target=0x0008:0x0010097b, DPL=0
Anyway if any of you have a great ideas, I would really appreciate the help!

Re: Global Descriptor Table Issues

Posted: Mon Dec 30, 2013 2:36 pm
by ApproximateIdentity
I totally forgot to add that if I turn off the -O2 compilation flag, it works perfectly fine. (Leaving the -O2 linker optimization on is okay.) I would think that this means that there is a problem with the structures used, but I have them ((packed)) so I'm not sure what I'm missing there...

Re: Global Descriptor Table Issues

Posted: Mon Dec 30, 2013 3:02 pm
by ApproximateIdentity
Hopefully I'm not being annoying with all of these posts, but I guess I have a more specific question which could be the problem. The only file which has errors when compiled with optimizations is my isr.c file which contains a isr_handler function. The function isr_handler is called from my asm isr code. Should I not compile the c file with optimizations?

It seems like the optimizations are somehow messing up my parameter passing. I'm calling isr_handler with a register_t structure argument which does not work, but if I rewrite the function to have no arguments, it does work with optimizations.

Here is the assembly code file interrupt.s that calls isr_handler:

Code: Select all

#
# interrupt.s -- Contains interrupt service routine wrappers.
#                Based on Bran's kernel development tutorials.
#                Rewritten for JamesM's kernel development tutorials.

# This macro creates a stub for an ISR which does NOT pass it's own
# error code (adds a dummy errcode byte).
.macro ISR_NOERRCODE num
.global isr\num
isr\num:
 cli
 push $0
 push $\num
 jmp isr_common_stub
.endm

# This macro creates a stub for an ISR which passes it's own
# error code.
.macro ISR_ERRCODE num
.global isr\num
isr\num:
 cli
 push $\num
 jmp isr_common_stub
.endm

ISR_NOERRCODE 0
ISR_NOERRCODE 1
ISR_NOERRCODE 2
ISR_NOERRCODE 3
ISR_NOERRCODE 4
ISR_NOERRCODE 5
ISR_NOERRCODE 6
ISR_NOERRCODE 7
ISR_ERRCODE   8
ISR_NOERRCODE 9
ISR_ERRCODE   10
ISR_ERRCODE   11
ISR_ERRCODE   12
ISR_ERRCODE   13
ISR_ERRCODE   14
ISR_NOERRCODE 15
ISR_NOERRCODE 16
ISR_NOERRCODE 17
ISR_NOERRCODE 18
ISR_NOERRCODE 19
ISR_NOERRCODE 20
ISR_NOERRCODE 21
ISR_NOERRCODE 22
ISR_NOERRCODE 23
ISR_NOERRCODE 24
ISR_NOERRCODE 25
ISR_NOERRCODE 26
ISR_NOERRCODE 27
ISR_NOERRCODE 28
ISR_NOERRCODE 29
ISR_NOERRCODE 30
ISR_NOERRCODE 31
 
#; This is our common ISR stub. It saves the processor state, sets
#; up for kernel mode segments, calls the C-level fault handler,
#; and finally restores the stack frame.
isr_common_stub:
 pusha                    # Pushes edi,esi,ebp,esp,ebx,edx,ecx,eax

 mov %ds, %ax               # Lower 16-bits of eax = ds.
 push %eax                 # save the data segment descriptor

 mov $0x10, %ax  # load the kernel data segment descriptor
 mov %ax, %ds
 mov %ax, %es
 mov %ax, %fs
 mov %ax, %gs

 call isr_handler # In isr.c

 pop %ebx        # reload the original data segment descriptor
 mov %bx, %ds
 mov %bx, %es
 mov %bx, %fs
 mov %bx, %gs

 popa                     # Pops edi,esi,ebp...
 add $8, %esp     # Cleans up the pushed error code and pushed ISR number
 sti
 iret           # pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP
Here is the isr.c file (I actually have the struct in a separate header file:

Code: Select all

struct registers {
    uint32_t ds;                  // Data segment selector
    uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; // Pushed by pusha.
    uint32_t int_no, err_code;    // Interrupt number and error code (if applicable)
    uint32_t eip, cs, eflags, useresp, ss; // Pushed by the processor automatically.
} __attribute__((packed));

typedef struct registers registers_t;

// This gets called from our ASM interrupt handler stub.
void
isr_handler(registers_t regs) {
    terminal_writestring("received interrupt: ");
    terminal_writenum(regs.int_no);
    terminal_writestring(", ");
    terminal_writenum(regs.err_code);
    terminal_writestring("\n");
}
If I change the isr_handler function to take no arguements, I can compile with optimizations fine:

Code: Select all

//
// isr.c -- High level interrupt service routines and interrupt request handlers.
//          Part of this code is modified from Bran's kernel development tutorials.
//          Rewritten for JamesM's kernel development tutorials.

#include <stdint.h>

#include "isr.h"
#include "monitor.h"

// This gets called from our ASM interrupt handler stub.
void
/*isr_handler(registers_t regs) {*/
isr_handler(void) {
    terminal_writestring("received interrupt: ");
    /*terminal_writenum(regs.int_no);*/
    terminal_writestring(", ");
    /*terminal_writenum(regs.err_code);*/
    terminal_writestring("\n");
}
Should I just turn off optimizations for my isr.c file? I read in these forums that all code should compile with optimizations so I'm reticent to do that...

Re: Global Descriptor Table Issues

Posted: Mon Dec 30, 2013 4:57 pm
by Owen
"registers_t" is too big to pass by value, so the compiler is implicitly doing pass by reference.

By pure blind luck, when you compile without optimization the stack lines up such that it works. When you compile with optimization on, your luck runs out and things break.

Re: Global Descriptor Table Issues

Posted: Mon Dec 30, 2013 5:53 pm
by ApproximateIdentity
Thanks so much! I can't believe the problem was so simple! I spent so long looking in the wrong direction! At least I can say that I learned a whole lot from searching (without success) for problem myself.

If you don't mind me asking, is there a standard size cut-off for structs to be passed by reference vs. value? Or is it specific to each compiler? (I searched for this question online, but haven't found an answer.)

In any case, thanks again! Now I got it working and can finally go on to the next part of the tutorial! :D