Page 2 of 3

Re: GDT doesn't work

Posted: Thu Jun 28, 2012 3:24 am
by leyley
Hobbes wrote:You're welcome. Now can you calculate the linear address of the GDT?
The liner address of GDT should be $BOOTSEG<<4+gdt, is that right? Cause now the BOOTSEG is a segment address now.
I decided to use paging directly after set cr0 (here not set), so the GDTR is a fixed value; To display a 'P' is just used to test whether I have enter the protected mode.

Re: GDT doesn't work

Posted: Thu Jun 28, 2012 3:45 am
by leyley
The new code:

Code: Select all


/* Boot file of nosdl;
 * This file is loaded at 0x10000;
 * Enter the protected mode and run init;
 * The max size of this file is 8k;
 */

#define BOOTSEG 0x1000	/* where I am in; */

/* Generate a gdt with 32bits base, 20bits limit and 12bits flag; 
 * We use a 32bits limit (low 20bits available) and
 * 16bits flag (lower 4bits of higher byte are always 0) here; 
 */

.text
.code16
.globl _start
_start:
	movl $0xB800,%eax
	movl %eax,%gs
	mov $'S',%al
	mov $0x0C,%ah
	movl %eax,%gs:((80*0+5)*2)
/* Prepare to enter the protected mode; */
__enter:
	/* Reset registers; */
	movl $BOOTSEG,%eax
	movl %eax,%ds
	/* Clear interrupt flags; */
	cli
	/* Load GDT; */
	lgdt gdtptr
	/* Open A20 Line; */
	inb $0x92,%al
	orb $0b00000010,%al
	outb %al,$0x92
	/* Set cr0, enter protected mode; */
	movl %cr0,%eax
	orl $0x01,%eax
	movl %eax,%cr0
	ljmp $0x10,$(__enter32)
/*
 * Here we enter the 32bits world;
 * The next step is init idt and other things;
 */
__enter32:
.code32
	/* Display a P; */
	xorl %eax,%eax
	movl $sel_video,%eax
	movl %eax,%gs
	movl $((80*0+10)*2),%edi
	mov $0x0F,%ah
	mov $'P',%al
	movl %eax,%gs:(%edi)
	jmp .
/* GDT table; */
.code16
gdt: 		.quad 0x0000000000000000	/* Not used; */
gdt_kstack: .quad 0x00CF92000000FFFF	/* Reserved for kernel stack; 0x08; */
gdt_kcode:  .quad 0x00CF9A000000FFFF	/* Kernel code segment; 0x10; */
gdt_kdata:  .quad 0x00CF92000000FFFF	/* Kernel data segment; 0x18; */
gdt_ustack: .quad 0x00CFF2000000FFFF	/* Reserved for user stack; 0x20; */
gdt_ucode:  .quad 0x00CFFA000000FFFF	/* User code segment; 0x28; */
gdt_udata:  .quad 0x00CFF2000000FFFF	/* User data segment; 0x30; */
gdt_video:  .quad 0x00CFF200B800FFFF	/* Video buffer; 0x38; */
		    .quad 0x0000000000000000	/* Not used; */
.set gdtlen, (.-gdt)	/* GDT Length; */
gdtptr: 	.2byte (gdtlen-1)	/* GDT Limit; */
gdtbase:	.4byte BOOTSEG<<4+gdt	/* GDT Base address; */
/* Selectors; */
.set sel_kcode, gdt_kcode-gdt
.set sel_kdata, gdt_kdata-gdt
.set sel_ucode, gdt_ucode-gdt
.set sel_udata, gdt_udata-gdt
.set sel_video, gdt_video-gdt
Is there any register that I should initialize before LGDT?
And this jump... do I need a ljmp or just jmp?

Re: GDT doesn't work

Posted: Thu Jun 28, 2012 3:52 am
by leyley
And my makefile, how powerful the dd is!

Code: Select all


# Makefile of nosdl;
CC = gcc
LD = ld
OBJCPY = objcopy
DD = dd
RM = rm
MOUNT = mount
UMOUNT = umount
LDOPTS =-Ttext 0x7c00
LDOPTB =-Ttext 0x0000
OCOPT = -R .pdr -R .comment -R .note -S -O binary
MIDFILES = boot.o boot.elf boot secboot.bin secboot.o secboot.elf
MKFS = mkfs.ext2
YES = yes
all:boot.img
secoot.o:secboot.S
	@$(CC) -c secboot.S
secboot.elf:secboot.o
	@$(LD) secboot.o -o secboot.elf $(LDOPTS)
secboot.bin:secboot.elf
	@$(OBJCPY) $(OCOPT) secboot.elf secboot.bin
boot.img:secboot.bin
	@$(DD) if=/dev/zero of=boot.img bs=512 count=2880
	@$(YES) | $(MKFS) boot.img 
	@$(DD) if=secboot.bin of=boot.img bs=512 count=2 conv=notrunc
boot.o:boot.S
	@$(CC) -c boot.S -Iinclude
boot.elf:boot.o
	@$(LD) boot.o -o boot.elf $(LDOPTB)
boot:boot.elf
	@$(OBJCPY) $(OCOPT) boot.elf boot
clean:
	@$(RM) -rf $(MIDFILES)
system:boot.img boot
	@sudo mount -o loop boot.img /home/ley/floppy
	@cp boot /home/ley/floppy
	@sleep 3
	@sudo umount /home/ley/floppy

Re: GDT doesn't work

Posted: Thu Jun 28, 2012 4:02 am
by leyley
And another thing, can I use VirtualBox to debug my program? I want to know the contents of registers.

Re: GDT doesn't work

Posted: Thu Jun 28, 2012 4:06 am
by Combuster
Is there any register that I should ritualized
it's "initialized", know your terminology :lol: (which begs the question, how often did you get corrected by the compiler's spelling?)
And this jump... do I need a ljmp or just jmp?
What is the difference between a far jump (what ljmp does, stupid GAS confusing people) and a near jump (jmp)? Have you read the manual on the matter?

Re: GDT doesn't work

Posted: Thu Jun 28, 2012 4:22 am
by leyley
Combuster wrote:
Is there any register that I should ritualized
it's "initialized", know your terminology :lol: (which begs the question, how often did you get corrected by the compiler's spelling?)
And this jump... do I need a ljmp or just jmp?
What is the difference between a far jump (what ljmp does, stupid GAS confusing people) and a near jump (jmp)? Have you read the manual on the matter?
:-) wrong spell of the word...
the limit of ljmp is 64kb, while jmp has the limit 256b?
I am using this book:Programming Ground Up, is there any AT&T asm manual I can use?

Re: GDT doesn't work

Posted: Thu Jun 28, 2012 4:38 am
by qw
Leyley, you are only seconds from somebody to tell you to RTFM. Knowing the difference between near and far jumps is a prerequisite for OS development.

Re: GDT doesn't work

Posted: Thu Jun 28, 2012 4:58 am
by Combuster
the limit of ljmp is 64kb, while jmp has the limit 256b?
you are only seconds from somebody to tell you to RTFM
In this case, I think "Whose code did you steal" would almost be more appropriate :shock:

@OP: Read the forum rules. In particular the "required knowledge" part.

Re: GDT doesn't work

Posted: Thu Jun 28, 2012 7:07 am
by JamesM
Hobbes wrote:Leyley, you are only seconds from somebody to tell you to RTFM. Knowing the difference between near and far jumps is a prerequisite for OS development.
You were wrong - it took Combuster 20 minutes from your post to his.

Maybe he was on lunch ;)

Re: GDT doesn't work

Posted: Thu Jun 28, 2012 7:33 am
by leyley
Combuster wrote:
the limit of ljmp is 64kb, while jmp has the limit 256b?
you are only seconds from somebody to tell you to RTFM
In this case, I think "Whose code did you steal" would almost be more appropriate :shock:

@OP: Read the forum rules. In particular the "required knowledge" part.
Thanks for the OP. As I said before, I am a rookie of this, I will collect the required knowledge before next post. As you said RTFM.
All of my codes are written by myself, I have read some codes but I never copy them, if you think it's stealing. I like the code style of BSD and the design of Linux, so I will using some thinking of them (if I will do I real OS, I will write comment where I find them, I have said the code above is just a practice). Whatever, thanks for you posts, I am going to RTFM now.

Re: GDT doesn't work

Posted: Thu Jun 28, 2012 7:47 am
by Combuster
JamesM wrote:
Hobbes wrote:Leyley, you are only seconds from somebody to tell you to RTFM. Knowing the difference between near and far jumps is a prerequisite for OS development.
You were wrong - it took Combuster 20 minutes from your post to his.

Maybe he was on lunch ;)
Technically, I already posted a covert RTFM 25 minutes before hobbes suggested it :wink:

Re: GDT doesn't work

Posted: Thu Jun 28, 2012 7:57 am
by turdus
leyley wrote:And another thing, can I use VirtualBox to debug my program? I want to know the contents of registers.
Yep, definitely RTFM. Here's the link (1st google result for keywords "virtualbox debugger"): http://www.virtualbox.org/manual/ch12.html#idp6899568

Re: GDT doesn't work

Posted: Thu Jun 28, 2012 11:29 am
by Nable
IMHO, bochs internal debugger seems much better

Re: GDT doesn't work

Posted: Thu Jun 28, 2012 11:38 am
by turdus
Nable wrote:IMHO, bochs internal debugger seems much better
Agreed. I've modified a bit (mostly printfs for more informative output, like RPL and IST when listing IDT), and now it's even more powerful.

Re: GDT doesn't work

Posted: Thu Jun 28, 2012 3:47 pm
by qw
Combuster wrote:Technically, I already posted a covert RTFM 25 minutes before hobbes suggested it :wink:
Always the man we can count on!