Qemu crashes after interrupt.

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.
Luca1
Posts: 15
Joined: Tue Apr 11, 2017 11:18 am

Qemu crashes after interrupt.

Post 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
User avatar
obiwac
Member
Member
Posts: 149
Joined: Fri Jan 27, 2017 12:15 pm
Libera.chat IRC: obiwac
Location: Belgium

Re: Qemu crashes after interrupt.

Post 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.
User avatar
obiwac
Member
Member
Posts: 149
Joined: Fri Jan 27, 2017 12:15 pm
Libera.chat IRC: obiwac
Location: Belgium

Re: Qemu crashes after interrupt.

Post by obiwac »

Luca1
Posts: 15
Joined: Tue Apr 11, 2017 11:18 am

Re: Qemu crashes after interrupt.

Post 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.
User avatar
iansjack
Member
Member
Posts: 4706
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: Qemu crashes after interrupt.

Post 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.
Luca1
Posts: 15
Joined: Tue Apr 11, 2017 11:18 am

Re: Qemu crashes after interrupt.

Post 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.
User avatar
dozniak
Member
Member
Posts: 723
Joined: Thu Jul 12, 2012 7:29 am
Location: Tallinn, Estonia

Re: Qemu crashes after interrupt.

Post 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?
Learn to read.
User avatar
iansjack
Member
Member
Posts: 4706
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: Qemu crashes after interrupt.

Post 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.
Luca1
Posts: 15
Joined: Tue Apr 11, 2017 11:18 am

Re: Qemu crashes after interrupt.

Post by Luca1 »

I just found the solution to my problem.
mallard
Member
Member
Posts: 280
Joined: Tue May 13, 2014 3:02 am
Location: Private, UK

Re: Qemu crashes after interrupt.

Post 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...)
Image
Luca1
Posts: 15
Joined: Tue Apr 11, 2017 11:18 am

Re: Qemu crashes after interrupt.

Post 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?
User avatar
iansjack
Member
Member
Posts: 4706
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: Qemu crashes after interrupt.

Post 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.
User avatar
xenos
Member
Member
Posts: 1121
Joined: Thu Aug 11, 2005 11:00 pm
Libera.chat IRC: xenos1984
Location: Tartu, Estonia
Contact:

Re: Qemu crashes after interrupt.

Post by xenos »

I doubt that QEMU crashes because you forgot to read the keyboard's status and data.
Programmers' Hardware Database // GitHub user: xenos1984; OS project: NOS
Luca1
Posts: 15
Joined: Tue Apr 11, 2017 11:18 am

Re: Qemu crashes after interrupt.

Post 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.
User avatar
matt11235
Member
Member
Posts: 286
Joined: Tue Aug 02, 2016 1:52 pm
Location: East Riding of Yorkshire, UK

Re: Qemu crashes after interrupt.

Post 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.
com.sun.java.swing.plaf.nimbus.InternalFrameInternalFrameTitlePaneInternalFrameTitlePaneMaximizeButtonWindowNotFocusedState
Compiler Development Forum
Post Reply