Page 1 of 1

Invalid opcode

Posted: Fri Jun 29, 2007 11:06 pm
by Pyrofan1
I keep getting this exception and i can't see why. cr0 and eflags contain the values i expect them to.

Posted: Sat Jun 30, 2007 12:45 pm
by Pyrofan1
okay, well here's a screenshot of the error
http://s176.photobucket.com/albums/w199 ... 0_1995.jpg

Posted: Sat Jun 30, 2007 3:17 pm
by frank
Do you know what piece of code is causing the exception?

It is a good idea to always initialize variables

Code: Select all

int x_pos;
int y_pos;
should be

Code: Select all

int x_pos = 0;
int y_pos = 0;
Also code you should be put into .c files and the prototypes for the functions should be put into .h files. You should never put functions in .h files unless they are inline. Doing so will cause many problems down the road when you include the header in more than 1 file.

Posted: Sat Jun 30, 2007 4:18 pm
by Pyrofan1
okay, well now i'm getting General Protection Fault Exceptions, http://s176.photobucket.com/albums/w199 ... 0_1997.jpg

Posted: Sat Jun 30, 2007 5:22 pm
by frank
Do you have a disk image so that I may troubleshoot it more?

Posted: Sat Jun 30, 2007 5:57 pm
by Pyrofan1

Posted: Sat Jun 30, 2007 6:17 pm
by Kevin McGuire
Specifying Linker Script
On your website the archive contains a typo in the build.sh shell scripts where it forgets to give the command line option -Tlinker.ld to the linker.

This causes the linker to leave the default virtual addresses for the sections, which of course in almost any case will not exist in memory during booting and did not in mine (since they are so high - around 128MB). The correct option is (below):
ld linker.ld loader.o kernel.o isr.o -o kernel.bin -Map kernel.map -Tlinker.ld

Stack Frame For C Calling Convention
Other than that it loads and raises a exception, I changed the loader.s to setup a stack frame for when calling a C function.

Code: Select all

_loader:
   	mov   $(stack + STACKSIZE), %esp # set up the stack
	push %esp
	mov %esp, %ebp
   	push  %eax                       # Multiboot magic number
   	push  %ebx                       # Multiboot data structure
   	call  _main            # call kernel proper
	nop
	hlt
VGA Routines Have Problems
I fiddled with the main function, and added my own print message function which appeared to get rid of the exception.

Code: Select all

#define VGA_WIDTH 80
#define VGA_HEIGHT 25
void puts(char *message, unsigned int x, unsigned int y, unsigned char color)
{
	unsigned int i;
	unsigned short *vmem = (unsigned short*)0xB8000;
	for(i = 0; message[i] != 0; ++i)
	{
		vmem[x + (y * VGA_WIDTH) + i] = (color << 8) | message[i];
	}
	return;
}

void _main(void* mbd,unsigned int magic)
{	
	unsigned short *vmem = (unsigned short*)0xB8000;
	vmem[0] = (1 << 8) | 'a';
	gdt_install();
	idt_install();	
	//text_color(WHITE,BLACK);
	clrscr();
	puts("Hello World", 0, 0, 0x12);
}
Apparently, the problem is somewhere in your video routines.

Separating Function Implementations From Header Files
You should also definitely place all that code into a source file like frank suggestion earlier for example:

gdt.h : Example

Code: Select all

#ifndef _PYROS_GDT
#define _PYROS_GDT
void gdt_flush();
void gdt_set_gate(int num,unsigned long base, unsigned long limit, unsigned char access, unsigned char gran);
void gdt_install();
#endif
gdt.c : Example

Code: Select all

/// Global Descriptor Table Utility Functions
/// gdt.c
/// 
struct gdt_entry gdt[3];
struct gdt_ptr gp;

void gdt_flush()
{
	asm("lgdt %0":"=g"(gp));
}

void gdt_set_gate(int num,unsigned long base,unsigned long limit,unsigned char access,unsigned char gran)
{
	gdt[num].base_low=(base&0xFFFF);
	gdt[num].base_middle=(base>>16)&0xFF;
    	gdt[num].base_high=(base>>24)&0xFF;

    	gdt[num].limit_low=(limit&0xFFFF);
    	gdt[num].granularity=((limit>>16)&0x0F);

    	gdt[num].granularity|=(gran&0xF0);
    	gdt[num].access=access;
}

void gdt_install()
{
    	gp.limit=(sizeof(struct gdt_entry)*3)-1;
    	gp.base=(unsigned int)&gdt;

    	gdt_set_gate(0,0,0,0,0);
    	gdt_set_gate(1,0,0xFFFFFFFF,0x9A,0xCF);
	gdt_set_gate(2,0,0xFFFFFFFF,0x92,0xCF);

    	gdt_flush();
}
Why have gdt.h And gdt.c?
If you try doing #include gdt.h in two different source files the linker (LD) will complain that there are multiple symbol definitions.

Right now you do not have to worry about it since you are only compiling one source file implicitly.
gcc -o kernel.o -c main.c -nostdlib -nostartfiles -nodefaultlibs -fno-stack-protector
ld linker.ld loader.o test.o kernel.o isr.o -o kernel.bin -Map kernel.map -Tlinker.ld


However, if you do this:

gcc -o kernel.o -c main.c -nostdlib -nostartfiles -nodefaultlibs -fno-stack-protector
gcc -o test.o -c test.c -nostdlib -nostartfiles -nodefaultlibs -fno-stack-protector
ld linker.ld loader.o test.o kernel.o isr.o -o kernel.bin -Map kernel.map -Tlinker.ld

And the test.c source file also does #include "gdt.h", the linker will complain and abort linking.

Miscellaneous
I am so appreciative that your kernel would actually compile, although this might be attributed to it being extremely simple. I have tried compiling so many other's kernel and could never get it to work just simply because it was so darn complicated. Thanks for including a build script (build system) or some type and placing the kernel image where it could be easily noticed for loading.

Posted: Sat Jun 30, 2007 7:27 pm
by Pyrofan1
thank you for your kind words and advice. i am happy to say that i no longer get any exceptions. :)

Posted: Sat Jun 30, 2007 7:30 pm
by Kevin McGuire
We should make a kernel together. I can make little things, or fix them.

Maybe, frank can help too?

Posted: Sat Jun 30, 2007 7:45 pm
by Pyrofan1
I'll PM you

Posted: Sat Jun 30, 2007 7:48 pm
by Kevin McGuire
okedoke, I sit right here and wait.

Posted: Sat Jun 30, 2007 8:47 pm
by frank
I have an os already. Fuzzy Logic. Its a beatifully ugly thing, but I am always happy to help other people with their OSs.