help on enabling pm interrupts, system is resetting

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.
Post Reply
spectrum
Member
Member
Posts: 37
Joined: Wed Jun 13, 2007 7:06 am

help on enabling pm interrupts, system is resetting

Post by spectrum »

hi all,

i'm quite new in os developement, and need some help about enabling inerrupts on a little pm os i'm trying to develope. I'm trying to prepare the PM ivt, as specified in the intel manual, with just the int 0x80, but after enabling interrupts (lidt) and trying to call int 80h the system reset.

This is the bochs output:

Code: Select all

00001062423d[CPU0 ] interrupt(): vector = 128, INT = 1, EXT = 0
00001062423e[CPU0 ] interrupt(): gate descriptor is not valid sys seg
00001062423d[CPU0 ] exception(0x0D)
00001062423d[CPU0 ] interrupt(): vector = 13, INT = 0, EXT = 1
00001062423e[CPU0 ] interrupt(): gate descriptor is not valid sys seg
00001062423d[CPU0 ] exception(0x0D)
00001062423d[CPU0 ] interrupt(): vector = 8, INT = 0, EXT = 1
00001062423e[CPU0 ] interrupt(): gate descriptor is not valid sys seg
00001062423d[CPU0 ] exception(0x0D)
00001062423i[CPU0 ] protected mode
00001062423i[CPU0 ] CS.d_b = 32 bit
00001062423i[CPU0 ] SS.d_b = 32 bit
00001062423i[CPU0 ] EFER   = 0x00000000
00001062423i[CPU0 ] | RAX=00000000000003f8  RBX=000000000000000e
00001062423i[CPU0 ] | RCX=0000000000000000  RDX=0000000000000400
00001062423i[CPU0 ] | RSP=000000000001ffdc  RBP=000000000001ffe8
00001062423i[CPU0 ] | RSI=00000000000001ab  RDI=00000000000001ab
00001062423i[CPU0 ] |  R8=0000000000000000   R9=0000000000000000
00001062423i[CPU0 ] | R10=0000000000000000  R11=0000000000000000
00001062423i[CPU0 ] | R12=0000000000000000  R13=0000000000000000
00001062423i[CPU0 ] | R14=0000000000000000  R15=0000000000000000
00001062423i[CPU0 ] | IOPL=0 id vip vif ac vm RF nt of df if tf sf ZF af PF cf
00001062423i[CPU0 ] | SEG selector     base    limit G D
00001062423i[CPU0 ] | SEG sltr(index|ti|rpl)     base    limit G D
00001062423i[CPU0 ] |  CS:0008( 0001| 0|  0) 00000000 000fffff 1 1
00001062423i[CPU0 ] |  DS:0010( 0002| 0|  0) 00000000 000fffff 1 1
00001062423i[CPU0 ] |  SS:0010( 0002| 0|  0) 00000000 000fffff 1 1
00001062423i[CPU0 ] |  ES:0010( 0002| 0|  0) 00000000 000fffff 1 1
00001062423i[CPU0 ] |  FS:0010( 0002| 0|  0) 00000000 000fffff 1 1
00001062423i[CPU0 ] |  GS:0018( 0003| 0|  0) 000b8000 00000f9f 0 0
00001062423i[CPU0 ] |  MSR_FS_BASE:0000000000000000
00001062423i[CPU0 ] |  MSR_GS_BASE:00000000000b8000
00001062423i[CPU0 ] | RIP=00000000000085a3 (00000000000085a3)
00001062423i[CPU0 ] | CR0=0x00000011 CR1=0x0 CR2=0x0000000000000000
00001062423i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
00001062423i[CPU0 ] >> int 0x80 : CD80
and thet is the involved part of my code

Code: Select all


#pragma pack(1)

struct _idt_reg {
	ushort	size;
	ulong		base;
} __attribute__ ((aligned(16)));

struct _idt_gate_desc {
	ushort	offset_procedure_0_15;
	ushort	segment_selector;
	ushort	zero:8;
	ushort	mask:8;
	ushort	offset_procedure_16_32;
};

#pragma pack()

struct _idt_reg  idtr;

static void _fill_idt (ulong int_n, ulong linear_offset)
{
	struct _idt_gate_desc  igd;
	
	kmemset	((unsigned char *)&igd, 0, sizeof(struct _idt_gate_desc));
	
	igd.offset_procedure_0_15		= (ushort) linear_offset & 0xffff;
	igd.segment_selector 			= (ushort) 0x08;
	igd.zero								= 0;
	igd.mask								= 0x8E;
	igd.offset_procedure_16_32		= (ushort) ((linear_offset>>16) & 0xffff);
	
	kmemcpy	(	_idt_start + ((int_n-1) * 8), 
					(unsigned char *)&igd, 
					sizeof(struct _idt_gate_desc)
				);
				
}

void k_load_ivt ()
{
	_fill_idt (0x80, (unsigned long)&_int_0x80);
	
	idtr.size = 255*8-1;
	idtr.base = 0;
	
	asm ("lidt	idtr");
	//asm ("sti"); 
   
   
				
	__asm__ __volatile__
	(
		"	pushl	$0x01				\n"
		"	int	$0x80				\n"
		"	addl	$4, %esp			\n"
	);
	
	for (;;);
	
}


every help or suggestion is very appreciated
many thanks,

angelo
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Post by AJ »

Hi,

Where does _idt_start point to? Your idtr.base suggestst that it is at the start of memory. Shouldn't idtr.base be _idt_start?

Also, rather than the memory copy if you had _idt_start as type _idt_gate_desc *, you could just add a new entry by doing:

Code: Select all

_idt_start[offset].offset_procedure_0_15 = &whatever;
...
...
HTH,
Adam
Last edited by AJ on Thu Jul 05, 2007 2:00 am, edited 1 time in total.
exkor
Member
Member
Posts: 111
Joined: Wed May 23, 2007 9:38 pm

Post by exkor »

Make sure you zero all 2KB of memory that your IDT takes.
idtr.base and _idt_start suppose to reference same memory,as far as I understand its where your IDT starts.

edited: Memory Mapped IO maybe located at 0 address even if RealMode IDT starts there.
spectrum
Member
Member
Posts: 37
Joined: Wed Jun 13, 2007 7:06 am

Post by spectrum »

thanks,


AJ,
for now i was planning to keep the idt starting just at 0, as done in real mode, but if you can suggest me a better offset, i will use it and,

fine, 've modified the gate table assignment way using the whole structure assignment.

exkor,
yes, idt start at 0, and _idt_start is at 0 too.
now i try to clean all the gates slots.

Thanks for now
spectrum
Member
Member
Posts: 37
Joined: Wed Jun 13, 2007 7:06 am

Post by spectrum »

nothing change after the table has been cleaned.

the error is always the same :(

00001072674e[CPU0 ] interrupt(): gate descriptor is not valid sys seg

maybe there can be a problem on my kernel segment type (the 0x08 offset), that is not system type ? I attach the gdt.

Code: Select all

gdtinfo:	.word		(gdtend - gdt -1)
			.long		gdt

gdt:		.long		0				/* null descriptor, as per convention gdt0 is 0 */
			.long		0
.equ codesel, .- gdt
desc_code: /* 32bit Flat Data, 0-4GB Writable */
			.word		0xFFFF		/* segment limit	 0:15 */
			.word		0				/* base address	 0:15 */
			.byte		0				/* base address	16:23 */
			.byte		0x9A			/*  1xP|2xDPL|1xS|4xtype				0x9A = 1|0 0|1|1010 */
			.byte		0xCF			/*  1xG|1xD/B|1x0|1xAVL|4xlimit		0xCF = 1|1|0|0|1111 */
			.byte		0				/*  base address	24:31 */
.equ datasel, .- gdt
desc_data:
			.word		0xFFFF		/* segment limit	 0:15 */
			.word		0				/* base address	 0:15 */
			.byte		0				/* base address	16:23 */
			.byte		0x92			/* 1xP|2xDPL|1xS|4xtype					0x92 = 1|0 0|1|0010 */
			.byte		0xCF			/* 1xG|1xD/B|1x0|1xAVL|4xlimit		0xCF = 1|1|0|0|1111 */
			.byte		0				/* base address	24:31 */
gdtend:
angelo
exkor
Member
Member
Posts: 111
Joined: Wed May 23, 2007 9:38 pm

Post by exkor »

You could move your IDT in safer location such as after where BIOS loads the bootsector (7e00h) or above 1mb(you can do that from protected mode or maybe from unreal).
And set limit of IDT to 80 entries otherwise you may have problems if IDT located above 7c00h: idtr.size = 81*8-1;

You can some look examples at http://www.osdever.net/tutorials.php?cat=0&sort=1
jnc100
Member
Member
Posts: 775
Joined: Mon Apr 09, 2007 12:10 pm
Location: London, UK
Contact:

Post by jnc100 »

Spectrum wrote:

Code: Select all

kmemcpy   (   _idt_start + ((int_n-1) * 8), 
I assume you're defining _idt_start to 0x0. By that logic, by calling this function with int_n as 0x80, you're actually setting entry 0x7F of the table, and 0x80 is still undefined. Get rid of the '-1' after int_n. If you're using bochs debugger, you can break on the int 0x80 call and check the output of 'info idt' there to make sure everything is set up properly.

As a side note, it probably isn't a good idea to overwrite your real mode idt because if you want to run v8086 services later, you're going to need it. Personally, I set up my idt above 1MB.

Regards,
John
spectrum
Member
Member
Posts: 37
Joined: Wed Jun 13, 2007 7:06 am

Post by spectrum »

jnc100,

that was the issue, infinite thanks and really congrats to have found it.

Was my stupid assumption, that interrupts start from integral 1, for this, 0x80 was condidered that had to stay at 0x7f position. Intel manual also show a picture where it puts "interupt #1" at position 0. That kept me out of the way.

Now works great.

Thanks all,

angelo
Post Reply