Page 1 of 1

Kernel Crashes after C main call

Posted: Thu Mar 19, 2009 10:12 am
by thestew42
So I have a boot loader that loads a second stage, then the second stage loads the kernel and jumps to it in pmode. The kernel has an assembly entry point that calls a C main function. I'm having a problem with the C code though. If the C main is empty or just has an infinite loop, it works fine, but when I add code to copy data to the video memory, it crashes and restarts.

The bochs log shows a 3rd exception (13) at the instruction that copies data to the video memory. I DAFS looking for the exception, but I couldn't find any information, and I don't know why this is happening because I've had programs with similar C code work.

This is the C code (I just took code from the barebones to make sure it wasn't my C code that was the problem):

Code: Select all

int main(void)
{
unsigned char *videoram = (unsigned char *) 0xb8000;
videoram[0] = 65; /* character 'A' */
videoram[1] = 0x07; /* forground, background color. */

return 0;
}
then this is the linker script:

Code: Select all

OUTPUT_FORMAT("binary")
ENTRY(start)
phys = 0x00100000;
SECTIONS
{
.text phys : AT(phys) {
code = .;
*(.text)
. = ALIGN(4096);
}
.rodata : AT(phys + (rodata - code))
{
rodata = .;
*(.rodata)
. = ALIGN(4096);
}
.data : AT(phys + (data - code))
{
data = .;
*(.data)
. = ALIGN(4096);
}
.bss : AT(phys + (bss - code))
{
bss = .;
*(.bss)
. = ALIGN(4096);
}
end = .;
}
Any suggestions would be appreciated. Thanks

Re: Kernel Crashes after C main call

Posted: Thu Mar 19, 2009 10:22 am
by Combuster
Could you post the entire bochs log?

Re: Kernel Crashes after C main call

Posted: Thu Mar 19, 2009 10:23 am
by thestew42
I'm not on my dev machine but I will later this afternoon

Re: Kernel Crashes after C main call

Posted: Thu Mar 19, 2009 11:45 am
by Firestryke31
Also, did you set up the data segments before jumping to the kernel? I've had that one bite me before.

Re: Kernel Crashes after C main call

Posted: Thu Mar 19, 2009 3:41 pm
by thestew42
Combuster wrote:Could you post the entire bochs log?
sure

Code: Select all

00000000000i[     ] Bochs x86 Emulator 2.3.7
00000000000i[     ]   Build from CVS snapshot, on June 3, 2008
00000000000i[     ] System configuration
00000000000i[     ]   processors: 1 (cores=1, HT threads=1)
00000000000i[     ]   A20 line support: yes
00000000000i[     ]   APIC support: yes
00000000000i[     ] CPU configuration
00000000000i[     ]   level: 6
00000000000i[     ]   SMP support: no
00000000000i[     ]   FPU support: yes
00000000000i[     ]   MMX support: yes
00000000000i[     ]   SSE support: 2
00000000000i[     ]   CLFLUSH support: yes
00000000000i[     ]   VME support: yes
00000000000i[     ]   3dnow! support: no
00000000000i[     ]   PAE support: yes
00000000000i[     ]   PGE support: yes
00000000000i[     ]   PSE support: yes
00000000000i[     ]   x86-64 support: yes
00000000000i[     ]   SEP support: yes
00000000000i[     ]   MWAIT support: no
00000000000i[     ]   XSAVE support: no
00000000000i[     ]   AES support: no
00000000000i[     ] Optimization configuration
00000000000i[     ]   Guest2HostTLB support: yes
00000000000i[     ]   RepeatSpeedups support: yes
00000000000i[     ]   Icache support: yes
00000000000i[     ]   Trace cache support: yes
00000000000i[     ]   Fast function calls: yes
00000000000i[     ] Devices configuration
00000000000i[     ]   ACPI support: yes
00000000000i[     ]   NE2000 support: yes
00000000000i[     ]   PCI support: yes
00000000000i[     ]   SB16 support: yes
00000000000i[     ]   USB support: yes
00000000000i[     ]   VGA extension support: vbe cirrus
00000000000i[MEM0 ] allocated memory at 024C0020. after alignment, vector=024C1000
00000000000i[MEM0 ] 32.00MB
00000000000i[MEM0 ] rom at 0xfffe0000/131072 ('BIOS-bochs-latest')
00000000000i[MEM0 ] rom at 0xc0000/38400 ('VGABIOS-lgpl-latest')
00000000000i[APIC?] set APIC ID to 0
00000000000i[APIC0] 80686
00000000000i[APIC0] local apic in CPU apicid=00 initializing
00000000000i[IOAP ] initializing I/O APIC
00000000000i[IOAP ] set APIC ID to 1
00000000000i[MEM0 ] Register memory access handlers: 0xfec00000 - 0xfec00fff
00000000000i[CMOS ] Using local time for initial clock
00000000000i[CMOS ] Setting initial clock to: Thu Mar 19 17:22:14 2009 (time0=1237497734)
00000000000i[DMA  ] channel 4 used by cascade
00000000000i[DMA  ] channel 2 used by Floppy Drive
00000000000i[FDD  ] fd0: 'floppy.img' ro=0, h=2,t=80,spt=18
00000000000i[PCI  ] 440FX Host bridge present at device 0, function 0
00000000000i[PCI  ] PIIX3 PCI-to-ISA bridge present at device 1, function 0
00000000000i[MEM0 ] Register memory access handlers: 0x000a0000 - 0x000bffff
00000000000i[WGUI ] Desktop Window dimensions: 1680 x 1050
00000000000i[WGUI ] Number of Mouse Buttons = 8
00000000000i[WGUI ] IME disabled
00000000000i[MEM0 ] Register memory access handlers: 0xe0000000 - 0xe07fffff
00000000000i[CLVGA] VBE Bochs Display Extension Enabled
00000000000i[CLVGA] interval=300000
00000000000i[     ] init_mem of 'harddrv' plugin device by virtual method
00000000000i[     ] init_mem of 'keyboard' plugin device by virtual method
00000000000i[     ] init_mem of 'serial' plugin device by virtual method
00000000000i[     ] init_mem of 'parallel' plugin device by virtual method
00000000000i[     ] init_mem of 'extfpuirq' plugin device by virtual method
00000000000i[     ] init_mem of 'gameport' plugin device by virtual method
00000000000i[     ] init_mem of 'speaker' plugin device by virtual method
00000000000i[     ] init_mem of 'pci_ide' plugin device by virtual method
00000000000i[     ] init_mem of 'acpi' plugin device by virtual method
00000000000i[     ] init_dev of 'harddrv' plugin device by virtual method
00000000000i[HD   ] Using boot sequence floppy, none, none
00000000000i[HD   ] Floppy boot signature check is enabled
00000000000i[     ] init_dev of 'keyboard' plugin device by virtual method
00000000000i[KBD  ] will paste characters every 1000 keyboard ticks
00000000000i[     ] init_dev of 'serial' plugin device by virtual method
00000000000i[SER  ] com1 at 0x03f8 irq 4
00000000000i[     ] init_dev of 'parallel' plugin device by virtual method
00000000000i[PAR  ] parallel port 1 at 0x0378 irq 7
00000000000i[     ] init_dev of 'extfpuirq' plugin device by virtual method
00000000000i[     ] init_dev of 'gameport' plugin device by virtual method
00000000000i[     ] init_dev of 'speaker' plugin device by virtual method
00000000000i[     ] init_dev of 'pci_ide' plugin device by virtual method
00000000000i[PCI  ] PIIX3 PCI IDE controller present at device 1, function 1
00000000000i[     ] init_dev of 'acpi' plugin device by virtual method
00000000000i[PCI  ] ACPI Controller present at device 1, function 3
00000000000i[     ] register state of 'harddrv' plugin device by virtual method
00000000000i[     ] register state of 'keyboard' plugin device by virtual method
00000000000i[     ] register state of 'serial' plugin device by virtual method
00000000000i[     ] register state of 'parallel' plugin device by virtual method
00000000000i[     ] register state of 'extfpuirq' plugin device by virtual method
00000000000i[     ] register state of 'gameport' plugin device by virtual method
00000000000i[     ] register state of 'speaker' plugin device by virtual method
00000000000i[     ] register state of 'pci_ide' plugin device by virtual method
00000000000i[     ] register state of 'acpi' plugin device by virtual method
00000000000i[SYS  ] bx_pc_system_c::Reset(HARDWARE) called
00000000000i[CPU0 ] cpu hardware reset
00000000000i[APIC0] local apic in CPU 0 initializing
00000000000i[     ] reset of 'harddrv' plugin device by virtual method
00000000000i[     ] reset of 'keyboard' plugin device by virtual method
00000000000i[     ] reset of 'serial' plugin device by virtual method
00000000000i[     ] reset of 'parallel' plugin device by virtual method
00000000000i[     ] reset of 'extfpuirq' plugin device by virtual method
00000000000i[     ] reset of 'gameport' plugin device by virtual method
00000000000i[     ] reset of 'speaker' plugin device by virtual method
00000000000i[     ] reset of 'pci_ide' plugin device by virtual method
00000000000i[     ] reset of 'acpi' plugin device by virtual method
00000003302i[BIOS ] $Revision: 1.209 $ $Date: 2008/06/02 20:08:10 $
00000320071i[KBD  ] reset-disable command received
00000443645i[VBIOS] VGABios $Id: vgabios.c,v 1.67 2008/01/27 09:44:12 vruppert Exp $

00000443716i[CLVGA] VBE known Display Interface b0c0
00000443748i[CLVGA] VBE known Display Interface b0c4
00000446673i[VBIOS] VBE Bios $Id: vbe.c,v 1.60 2008/03/02 07:47:21 vruppert Exp $
00000769674i[BIOS ] Starting rombios32
00000770501i[BIOS ] ram_size=0x02000000
00000870157i[BIOS ] Found 1 cpu(s)
00000886458i[BIOS ] bios_table_addr: 0x000fb778 end=0x000fcc00
00000886525i[PCI  ] 440FX PMC write to PAM register 59 (TLB Flush)
00001345332i[PCI  ] 440FX PMC write to PAM register 59 (TLB Flush)
00001804819i[P2I  ] PCI IRQ routing: PIRQA# set to 0x0b
00001804866i[P2I  ] PCI IRQ routing: PIRQB# set to 0x09
00001804913i[P2I  ] PCI IRQ routing: PIRQC# set to 0x0b
00001804960i[P2I  ] PCI IRQ routing: PIRQD# set to 0x09
00001804976i[P2I  ] write: ELCR2 = 0x0a
00001805913i[BIOS ] PIIX3 init: elcr=00 0a
00001826168i[BIOS ] PCI: bus=0 devfn=0x00: vendor_id=0x8086 device_id=0x1237
00001829405i[BIOS ] PCI: bus=0 devfn=0x08: vendor_id=0x8086 device_id=0x7000
00001832138i[BIOS ] PCI: bus=0 devfn=0x09: vendor_id=0x8086 device_id=0x7010
00001832599i[PIDE ] new BM-DMA address: 0xc000
00001833482i[BIOS ] region 4: 0x0000c000
00001836058i[BIOS ] PCI: bus=0 devfn=0x0b: vendor_id=0x8086 device_id=0x7113
00001836558i[ACPI ] new irq line = 11
00001836595i[ACPI ] new PM base address: 0xb000
00001836657i[ACPI ] new SM base address: 0xb100
00001837125i[CPU0 ] Enter to System Management Mode
00001837135i[CPU0 ] RSM: Resuming from System Management Mode
00001837169i[PCI  ] setting SMRAM control register to 0x4a
00001837451i[PCI  ] setting SMRAM control register to 0x0a
00001860732i[BIOS ] MP table addr=0x000fb850 MPC table addr=0x000fb780 size=0xd0
00001862935i[BIOS ] SMBIOS table addr=0x000fb860
00001865979i[BIOS ] ACPI tables: RSDP addr=0x000fb970 ACPI DATA addr=0x01ff0000 size=0x9d8
00001885512i[PCI  ] 440FX PMC write to PAM register 59 (TLB Flush)
00001886524i[BIOS ] bios_table_cur_addr: 0x000fb994
00003000000i[WGUI ] dimension update x=720 y=400 fontheight=16 fontwidth=9 bpp=8
00032315724i[BIOS ] Booting from 0000:7c00
00040924907e[CPU0 ] write_virtual_checks(): write beyond limit, r/w
00040924907e[CPU0 ] fetch_raw_descriptor: GDT: index (f007)1e00 > limit (17)
00040924907i[CPU0 ] CPU is in protected mode (active)
00040924907i[CPU0 ] CS.d_b = 32 bit
00040924907i[CPU0 ] SS.d_b = 16 bit
00040924907i[CPU0 ] EFER   = 0x00000000
00040924907i[CPU0 ] | RAX=0000000000000000  RBX=0000000000000007
00040924907i[CPU0 ] | RCX=000000000000000d  RDX=0000000000000fff
00040924907i[CPU0 ] | RSP=0000000000102ff0  RBP=0000000000102ff8
00040924907i[CPU0 ] | RSI=00000000ffff08c7  RDI=0000000000080005
00040924907i[CPU0 ] |  R8=0000000000000000   R9=0000000000000000
00040924907i[CPU0 ] | R10=0000000000000000  R11=0000000000000000
00040924907i[CPU0 ] | R12=0000000000000000  R13=0000000000000000
00040924907i[CPU0 ] | R14=0000000000000000  R15=0000000000000000
00040924907i[CPU0 ] | IOPL=0 id vip vif ac vm RF nt of df if tf sf zf af PF cf
00040924907i[CPU0 ] | SEG selector     base    limit G D
00040924907i[CPU0 ] | SEG sltr(index|ti|rpl)     base    limit G D
00040924907i[CPU0 ] |  CS:0008( 0001| 0|  0) 00000000 000fffff 1 1
00040924907i[CPU0 ] |  DS:0010( 0002| 0|  0) 00000000 000fffff 1 1
00040924907i[CPU0 ] |  SS:0000( 0005| 0|  0) 00000000 0000ffff 0 0
00040924907i[CPU0 ] |  ES:0010( 0002| 0|  0) 00000000 000fffff 1 1
00040924907i[CPU0 ] |  FS:07c0( 0005| 0|  0) 00007c00 0000ffff 0 0
00040924907i[CPU0 ] |  GS:07c0( 0005| 0|  0) 00007c00 0000ffff 0 0
00040924907i[CPU0 ] |  MSR_FS_BASE:0000000000007c00
00040924907i[CPU0 ] |  MSR_GS_BASE:0000000000007c00
00040924907i[CPU0 ] | RIP=0000000000003050 (0000000000003050)
00040924907i[CPU0 ] | CR0=0x60000011 CR1=0x0 CR2=0x0000000000000000
00040924907i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
00040924907i[CPU0 ] >> mov dword ptr ss:[ebp+0xfffffffc], 0x000b8000 : C745FC00800B00
00040924907e[CPU0 ] exception(): 3rd (13) exception with no resolution, shutdown status is 00h, resetting
00040924907i[SYS  ] bx_pc_system_c::Reset(SOFTWARE) called
00040924907i[CPU0 ] cpu software reset
00040924907i[APIC0] local apic in CPU 0 initializing
00040928210i[BIOS ] $Revision: 1.209 $ $Date: 2008/06/02 20:08:10 $
00041245055i[KBD  ] reset-disable command received
After that it just repeats
Firestryke31 wrote:Also, did you set up the data segments before jumping to the kernel? I've had that one bite me before.
Like in the linker file? I have them there. This is the entry assembly file. I'm now using one from Bran's

Code: Select all

; This is the kernel's entry point. We could either call main here,
; or we can use this to setup the stack or other nice stuff, like
; perhaps setting up the GDT and segments. Please note that interrupts
; are disabled at this point: More on interrupts later!
[BITS 32]
global start
start:
    mov esp, _sys_stack     ; This points the stack to our new stack area
	mov ax, 10h
	mov ds, ax
	mov es, ax
    jmp stublet

; This part MUST be 4byte aligned, so we solve that issue using 'ALIGN 4'
ALIGN 4
mboot:
    ; Multiboot macros to make a few lines later more readable
    MULTIBOOT_PAGE_ALIGN	equ 1<<0
    MULTIBOOT_MEMORY_INFO	equ 1<<1
    MULTIBOOT_AOUT_KLUDGE	equ 1<<16
    MULTIBOOT_HEADER_MAGIC	equ 0x1BADB002
    MULTIBOOT_HEADER_FLAGS	equ MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO | MULTIBOOT_AOUT_KLUDGE
    MULTIBOOT_CHECKSUM	equ -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
    EXTERN code, bss, end

    ; This is the GRUB Multiboot header. A boot signature
    dd MULTIBOOT_HEADER_MAGIC
    dd MULTIBOOT_HEADER_FLAGS
    dd MULTIBOOT_CHECKSUM
    
    ; AOUT kludge - must be physical addresses. Make a note of these:
    ; The linker script fills in the data for these ones!
    dd mboot
    dd code
    dd bss
    dd end
    dd start

; This is an endless loop here. Make a note of this: Later on, we
; will insert an 'extern _main', followed by 'call _main', right
; before the 'jmp $'.
stublet:
	extern _main
    call _main
	jmp $


; Shortly we will add code for loading the GDT right here!


; In just a few pages in this tutorial, we will add our Interrupt
; Service Routines (ISRs) right here!



; Here is the definition of our BSS section. Right now, we'll use
; it just to store the stack. Remember that a stack actually grows
; downwards, so we declare the size of the data before declaring
; the identifier '_sys_stack'
SECTION .bss
    resb 8192               ; This reserves 8KBytes of memory here
_sys_stack:
berkus wrote:You are sure "return 0;" is ok there? You have the hlt/jmp $ after call to main to handle that?
I do:

Code: Select all

stublet:
	extern _main
    call _main
	jmp $
and the error is

Code: Select all

00040924907i[CPU0 ] >> mov dword ptr ss:[ebp+0xfffffffc], 0x000b8000 : C745FC00800B00
00040924907e[CPU0 ] exception(): 3rd (13) exception with no resolution, shutdown status is 00h, resetting

Re: Kernel Crashes after C main call

Posted: Thu Mar 19, 2009 4:19 pm
by neonek
You don't have IRQ handling code in your kernel, so try adding cli instruction before

Code: Select all

mov esp, _sys_stack
It'll help, I think.

Regards,
Mark

Re: Kernel Crashes after C main call

Posted: Thu Mar 19, 2009 4:24 pm
by thestew42
neonek wrote:You don't have IRQ handling code in your kernel, so try adding cli instruction before

Code: Select all

mov esp, _sys_stack
It'll help, I think.

Regards,
Mark
Hmmmm. Thanks, well that's probably a good idea. I tried it though and I still get the same error :(

Re: Kernel Crashes after C main call

Posted: Thu Mar 19, 2009 5:35 pm
by Combuster
So your code is saying that it uses GRUB, and you say you're using your own bootloader...

Anyway, your segment registers have not been reloaded with their correct 4G limit versions - check your bootloader for that.
00040924907e[CPU0 ] write_virtual_checks(): write beyond limit, r/w
(...)
00040924907i[CPU0 ] | SS:0000( 0005| 0| 0) 00000000 0000ffff 0 0