setting up GDT??

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
fei
Posts: 10
Joined: Sat Jul 07, 2007 4:40 am

setting up GDT??

Post by fei »

I'm following up Bran's Kernel Development tutorial (http://www.osdever.net/bkerndev/Docs/gdt.htm). When I failed at seting up GDT. I can't quite understand the far jmp in the code ("jmp 0x08:flush2"). I convert the nasm code to gas ("ljmp $0x80, $flush2"). My kernel just freeze after startup. If I comment out the far jmp, it works fine. Why is called jar jmp? why do I need it? How can I fix the problem?

Thanks in advance!!!

This is the original code

Code: Select all

global _gdt_flush
extern _gp
_gdt_flush:
    lgdt [_gp]
    mov ax, 0x10
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax
    mov ss, ax
    jmp 0x08:flush2
flush2:
    ret

This is my code in gas

Code: Select all

.global _gdt_flush
.extern _gdt_p
.type _gdt_flush @function
 _gdt_flush:
 	lgdt (_gdt_p)
 	mov $0x10, %ax
 	mov %ax, %ds
 	mov %ax, %es
 	mov %ax, %fs
 	mov %ax, %gs
 	mov %ax, %ss
	ljmp $0x80, $flush2
flush2:
	ret
frank
Member
Member
Posts: 729
Joined: Sat Dec 30, 2006 2:31 pm
Location: East Coast, USA

Post by frank »

The far jump is necessary to make the processor update the hidden fields for cs.

For anyone to be able to solve your problem we need to know a little bit more information about your kernel.
Are you using grub?
Is your kernel only assembly or is it mixed assembly and C?
Can we see the code that sets up the GDT?
fei
Posts: 10
Joined: Sat Jul 07, 2007 4:40 am

Post by fei »

> Are you using grub?
Yes. I'm using grub

> Is your kernel only assembly or is it mixed assembly and C?
It's mixed assembly and C.

I found out the problem. I changed the _gdt_p.base to tyep "void *' instead of unsigned int. This is the problem. After I changed back to use unsigned int, it works fine.

"void *' and "unsigned int" both have the same size. I tought it's a proper way to use "void *' when dealing with pointers. So, what is the difference between these two types?? I'm a bit confused.

Thanks!

Code: Select all

struct gdt_ptr {
	unsigned short limit;
	unsigned int base;
	//void *base;
}__attribute__((packed));

struct gdt_ptr _gdt_p;

_gdt_p.limit = (sizeof(struct gdt_entry) * 3) - 1;
_gdt_p.base = (unsigned int)(&gdt);
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Post by pcmattman »

Of course they have the same size - an address on the x86 in PMode is 32 bits long. Read up on pointers 8)
earlz
Member
Member
Posts: 1546
Joined: Thu Jul 07, 2005 11:00 pm
Contact:

Post by earlz »

It was probably something to do with pointer addition or something...though you would think they would compile to be the same..
frank
Member
Member
Posts: 729
Joined: Sat Dec 30, 2006 2:31 pm
Location: East Coast, USA

Post by frank »

I'm glad you fixed it. I'm sorry I couldn't be of more help.

Now about the void * versus unsigned int thing:

I looked at the disassembly of accessing two different structs that look just like gdt_ptr. One with void * and one with unsigned int. In the generated assembly there is absolutely no difference between the two. The only thing I could think of is if you were to forget the & in front of gdt when you did it with void *.
fei
Posts: 10
Joined: Sat Jul 07, 2007 4:40 am

Post by fei »

I'm glad you fixed it. I'm sorry I couldn't be of more help.
No worry. Thanks again for your help. "void *" and "unsigned int" ARE the same. I tried to use "void *" again and it just works. Don't remember what was the original code. Sorry for asking a question without carefully thinking it before.
Post Reply