Page 1 of 2

Qemu crashes after interrupt.

Posted: Tue Apr 11, 2017 12:19 pm
by Luca1
Hello everyone,

as the title says as soon as there is an interrupt my function is called and works fine, but then qemu crashes:

Code: Select all

qemu: fatal: Trying to execute code outside RAM or ROM at 0x000a0000

EAX=00000f02 EBX=00002a00 ECX=00100482 EDX=00000000
ESI=00000000 EDI=00103fff EBP=00000000 ESP=001025e0
EIP=0009fff0 EFL=00000202 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
CS =0008 00000000 ffffffff 00cf9a00 DPL=0 CS32 [-R-]
SS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
DS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
FS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
GS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS32-busy
GDT=     000caa68 00000027
IDT=     001025e0 00000800
CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000 
DR6=ffff0ff0 DR7=00000400
CCS=00000f02 CCD=00000f0b CCO=ADDB    
EFER=0000000000000000
FCW=037f FSW=0000 [ST=0] FTW=00 MXCSR=00001f80
FPR0=0000000000000000 0000 FPR1=0000000000000000 0000
FPR2=0000000000000000 0000 FPR3=0000000000000000 0000
FPR4=0000000000000000 0000 FPR5=0000000000000000 0000
FPR6=0000000000000000 0000 FPR7=0000000000000000 0000
XMM00=00000000000000000000000000000000 XMM01=00000000000000000000000000000000
XMM02=00000000000000000000000000000000 XMM03=00000000000000000000000000000000
XMM04=00000000000000000000000000000000 XMM05=00000000000000000000000000000000
XMM06=00000000000000000000000000000000 XMM07=00000000000000000000000000000000


Assembler code:

Code: Select all

bits 32
section .text
        ;multiboot spec
        align 4
        dd 0x1BADB002
        dd 0x00 
        dd - (0x1BADB002 + 0x00)

global start
global inb
global outb
global load_idt
global interrupt_handle

extern kmain
extern cihandle

start:
	cli
	mov esp, stack_space	
	
	call kmain
	hlt
	
inb:
	mov edx, [esp + 4]
	in al, dx	
	ret

outb:
	mov edx, [esp + 4]
	mov al, [esp + 4 + 4]  
	out dx, al  
	ret
	
load_idt:
	mov edx, [esp + 4]
	lidt [edx]
	sti
	ret

interrupt_handle:
	call cihandle
	iretd                          ;if I change this to ret the kernel continues to run, but doesn't catch any more interrupts

section .bss
resb 8192
stack_space:
C Code:

Code: Select all

#define COM1 0x3f8
#define PITM 0x43
#define PIT0 0x40
#define IDT_SIZE 256

extern char inb(unsigned short port);
extern void outb(unsigned short port, unsigned char data);
extern void load_idt(unsigned long *idt_ptr);
extern void interrupt_handle(void);

struct IDT_entry {
	unsigned short int offset_lowerbits;
	unsigned short int selector;
	unsigned char zero;
	unsigned char type_attr;
	unsigned short int offset_higherbits;
};

struct IDT_entry IDT[IDT_SIZE];

char* itoa(int i, int base){
    char const digit[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    char* p;
    if(i<0){
        *p++ = '-';
        i *= -1;
    }
    int shifter = i;
    do{ //Move to where representation ends
        ++p;
        shifter = shifter/base;
    }while(shifter);
    *p = '\0';
    do{ //Move back, inserting digits as u go
        *--p = digit[i%base];
        i = i/base;
    }while(i);
    return p;
}

int is_transmit_empty(unsigned short port) {
   return inb(port + 5) & 0x20;
}


void write_serial(char a, unsigned short port) {
   while (is_transmit_empty(port) == 0);
 
   outb(port,a);
}

void write_mul(char *a, unsigned short port) {
	unsigned int j = 0;
	while(a[j] != '\0') {
		write_serial(a[j], port);
		++j;
	}
}
 
void init_serial(unsigned short port) {
   outb(port + 1, 0x00);    // Disable all interrupts
   outb(port + 3, 0x80);    // Enable DLAB (set baud rate divisor)
   outb(port + 0, 0x03);    // Set divisor to 3 (lo byte) 38400 baud
   outb(port + 1, 0x00);    //                  (hi byte)
   outb(port + 3, 0x03);    // 8 bits, no parity, one stop bit
   outb(port + 2, 0xC7);    // Enable FIFO, clear them, with 14-byte threshold
   outb(port + 4, 0x0B);    // IRQs enabled, RTS/DSR set
}

void print(char *str) {
	int i = 0;
	int j = 0;
	char *vidptr = (char*)0xb8000;
	while (str[i] != '\0') {
		vidptr[j] = str[i];
		j = j + 2;
		++i;
	}
}

int initirq() {
	
	unsigned long interrupt_address = (unsigned long) interrupt_handle;
	
	
	unsigned long idt_address;
	unsigned long idt_ptr[2];
	
	IDT[0x21].offset_lowerbits = interrupt_address & 0xFFFF;
	IDT[0x21].selector = 0x08;
	IDT[0x21].zero = 0;
	IDT[0x21].type_attr = 0x8e;
	IDT[0x21].offset_higherbits = (interrupt_address & 0xFFFF0000) >> 16;
	
	
	/* ICW1 - begin initialization */
	outb(0x20 , 0x11);
	outb(0xA0 , 0x11);

	/* ICW2 - remap offset address of IDT */
	/*
	* In x86 protected mode, we have to remap the PICs beyond 0x20 because
	* Intel have designated the first 32 interrupts as "reserved" for cpu exceptions
	*/
	outb(0x21 , 0x20);
	outb(0xA1 , 0x28);

	/* ICW3 - setup cascading */
	outb(0x21 , 0x00);
	outb(0xA1 , 0x00);

	/* ICW4 - environment info */
	outb(0x21 , 0x01);
	outb(0xA1 , 0x01);
	/* Initialization finished */

	
	outb(0x21, 0xFD);
	outb(0xA1, 0xFF);
	
	idt_address = (unsigned long)IDT;
	idt_ptr[0] = sizeof (struct IDT_entry) * IDT_SIZE + ((idt_address & 0xFFFFF) << 16);
	idt_ptr[1] = idt_address >> 16;
	
	load_idt(idt_ptr);
	
}

void cihandle(void) {
	
	outb(0x20, 0x20);
	outb(COM1, 'A');
	return;
	
}

void kmain(void)
{
	init_serial(COM1);
	init_serial(PITM);
	init_serial(PIT0);
	
	
	write_serial(0x00, PITM);
	
		initirq();
	
	write_mul("Hello World!", COM1);
	char *str = "hello kernel!";
	/* video memory begins at address 0xb8000 */
	char *vidptr = (char*)0xb8000;
	unsigned int i = 0;
	unsigned int j = 0;
	unsigned int screensize;

	/* this loops clears the screen
	* there are 25 lines each of 80 columns; each element takes 2 bytes */
	screensize = 80 * 25 * 2;
	while (j < screensize) {
		vidptr[j] = ' ';
		vidptr[j+1] = 0x0F;
		j = j + 2;
	}

	/*
	j = 0;
	str = itoa(0xAA, 16);
	while (str[i] != '\0') {
		vidptr[j] = str[i];
		j = j + 2;
		++i;
	}*/
}

Thanks in advance,
Luca

Re: Qemu crashes after interrupt.

Posted: Tue Apr 11, 2017 1:48 pm
by obiwac
I would first of all advise you to organize your code in separate files. It will be easier to find the problem without any distractions from code that has nothing to do with your problem.

Re: Qemu crashes after interrupt.

Posted: Tue Apr 11, 2017 1:52 pm
by obiwac

Re: Qemu crashes after interrupt.

Posted: Tue Apr 11, 2017 11:13 pm
by Luca1
obiwac wrote:I would first of all advise you to organize your code in separate files. It will be easier to find the problem without any distractions from code that has nothing to do with your problem.
I am just trying stuff our right now, that's why I only have 1 file, here is everything removed that has nothing to do with the interrupts:

Code: Select all

#define COM1 0x3f8
#define IDT_SIZE 256

extern char inb(unsigned short port);
extern void outb(unsigned short port, unsigned char data);
extern void load_idt(unsigned long *idt_ptr);
extern void interrupt_handle(void);

struct IDT_entry {
   unsigned short int offset_lowerbits;
   unsigned short int selector;
   unsigned char zero;
   unsigned char type_attr;
   unsigned short int offset_higherbits;
};

struct IDT_entry IDT[IDT_SIZE];


int initirq() {
   
   unsigned long interrupt_address = (unsigned long) interrupt_handle;
   
   
   unsigned long idt_address;
   unsigned long idt_ptr[2];
   
   IDT[0x21].offset_lowerbits = interrupt_address & 0xFFFF;
   IDT[0x21].selector = 0x08;
   IDT[0x21].zero = 0;
   IDT[0x21].type_attr = 0x8e;
   IDT[0x21].offset_higherbits = (interrupt_address & 0xFFFF0000) >> 16;
   
   
   /* ICW1 - begin initialization */
   outb(0x20 , 0x11);
   outb(0xA0 , 0x11);

   /* ICW2 - remap offset address of IDT */
   /*
   * In x86 protected mode, we have to remap the PICs beyond 0x20 because
   * Intel have designated the first 32 interrupts as "reserved" for cpu exceptions
   */
   outb(0x21 , 0x20);
   outb(0xA1 , 0x28);

   /* ICW3 - setup cascading */
   outb(0x21 , 0x00);
   outb(0xA1 , 0x00);

   /* ICW4 - environment info */
   outb(0x21 , 0x01);
   outb(0xA1 , 0x01);
   /* Initialization finished */

   
   outb(0x21, 0xFD);
   outb(0xA1, 0xFF);
   
   idt_address = (unsigned long)IDT;
   idt_ptr[0] = sizeof (struct IDT_entry) * IDT_SIZE + ((idt_address & 0xFFFFF) << 16);
   idt_ptr[1] = idt_address >> 16;
   
   load_idt(idt_ptr);
   
}

void cihandle(void) {
   
   outb(0x20, 0x20);
   outb(COM1, 'A');
   return;
   
}

void kmain(void)
{
   init_serial(COM1);
   initirq();
}
I already looked there and nothing really describes my case.

Re: Qemu crashes after interrupt.

Posted: Wed Apr 12, 2017 12:58 am
by iansjack
In that case you are going to have to do some debugging. Use gdb to single-step your code so that you can see what is happening.

Re: Qemu crashes after interrupt.

Posted: Wed Apr 12, 2017 2:34 am
by Luca1
iansjack wrote:In that case you are going to have to do some debugging. Use gdb to single-step your code so that you can see what is happening.
I know what's happening, I just don't know why. For some reason after calling the interrupt_handle the program doesn't jump back to the correct location, but I don't know why.

Re: Qemu crashes after interrupt.

Posted: Wed Apr 12, 2017 3:35 am
by dozniak
Luca1 wrote:
iansjack wrote:In that case you are going to have to do some debugging. Use gdb to single-step your code so that you can see what is happening.
I know what's happening, I just don't know why. For some reason after calling the interrupt_handle the program doesn't jump back to the correct location, but I don't know why.
Stack problems? Are you popping stuff correctly in an IRET? Are you storing it there correctly?

Re: Qemu crashes after interrupt.

Posted: Wed Apr 12, 2017 4:07 am
by iansjack
Luca1 wrote:I know what's happening, I just don't know why. For some reason after calling the interrupt_handle the program doesn't jump back to the correct location, but I don't know why.
At the risk of seeming rude, you have no idea what is happening. (If you did you would know what was causing it.)

Do you know the contents of the registers before the crash? How do you know exactly which instruction the program is executing when it crashes? Do you know the state of the stack? Do you know how the stack go into that state? (That's, fairly obviously, the cause of your problem.) Is your stack even valid?

Why the reluctance to use a debugger, which will let you inspect these things and determine exactly how you got to a state which leads to a crash? If you don't know how to use a debugger, now is an excellent time to learn on a trivial error.

Re: Qemu crashes after interrupt.

Posted: Wed Apr 12, 2017 4:16 am
by Luca1
I just found the solution to my problem.

Re: Qemu crashes after interrupt.

Posted: Wed Apr 12, 2017 4:22 am
by mallard
Luca1 wrote:I just found the solution to my problem.
That's literally the worst possible forum post ever. Never, ever, ever do that. Even if you find the solution to your problem yourself always explain it in a post. Forums aren't just a private conversation between posters, they're a record and "knowledge-base" for future readers and are indexed by search engines. If someone with a similar problem in the future comes across this thread, you've just made it needlessly frustrating and difficult for them to find the answer.

(I'm no fan of "just Google it" or "RTFM" answers for anything but the most trivial and well-documented issues either; all too often the manuals become hard to find or those threads become top hits on Google...)

Re: Qemu crashes after interrupt.

Posted: Wed Apr 12, 2017 4:29 am
by Luca1
mallard wrote:
Luca1 wrote:I just found the solution to my problem.
That's literally the worst possible forum post ever. Never, ever, ever do that. Even if you find the solution to your problem yourself always explain it in a post. Forums aren't just a private conversation between posters, they're a record and "knowledge-base" for future readers and are indexed by search engines. If someone with a similar problem in the future comes across this thread, you've just made it needlessly frustrating and difficult for them to find the answer.

(I'm no fan of "just Google it" or "RTFM" answers for anything but the most trivial and well-documented issues either; all too often the manuals become hard to find or those threads become top hits on Google...)
Oh sorry, because everyone else was just pointing at some stuff I already read I thought non helpful answers were the forum standard. Because I first tried to catch interrupts from the PIT and then switched to the keyboard interrupts because they are easier to control I didn't read in the Status and Data which caused problems. Happy?

Re: Qemu crashes after interrupt.

Posted: Wed Apr 12, 2017 4:34 am
by iansjack
Luca1 wrote:Oh sorry, because everyone else was just pointing at some stuff I already read I thought non helpful answers were the forum standard.
You have a real knack for making friends and influencing people.

Re: Qemu crashes after interrupt.

Posted: Wed Apr 12, 2017 5:08 am
by xenos
I doubt that QEMU crashes because you forgot to read the keyboard's status and data.

Re: Qemu crashes after interrupt.

Posted: Wed Apr 12, 2017 8:48 am
by Luca1
XenOS wrote:I doubt that QEMU crashes because you forgot to read the keyboard's status and data.
Well then give me another reason why my code works afterwards.
iansjack wrote:You have a real knack for making friends and influencing people.
Sorry, but if all people in the OS dev community are as "open" to new people as some people in this thread I am not sure if I want/need friends in here.

Re: Qemu crashes after interrupt.

Posted: Wed Apr 12, 2017 9:01 am
by matt11235
Luca1 wrote:Sorry, but if all people in the OS dev community are as "open" to new people as some people in this thread I am not sure if I want/need friends in here.
imo this is one of the nicest places on the internet.

You just walked in, threw your code on the table and asked other people to fix it and then got upset when nobody spoon fed you more code. There's nothing wrong with asking for help, but you need to put some effort in yourself.