Page 1 of 1

higher half tutorial question

Posted: Sat Feb 28, 2009 10:42 am
by yemista
I have a question about this part of the code

Code: Select all

BootPageDirectory:
    ; This page directory entry identity-maps the first 4MB of the 32-bit physical address space.
    ; All bits are clear except the following:
    ; bit 7: PS The kernel page is 4MB.
    ; bit 1: RW The kernel page is read/write.
    ; bit 0: P  The kernel page is present.
    ; This entry must be here -- otherwise the kernel will crash immediately after paging is
    ; enabled because it can't fetch the next instruction! It's ok to unmap this page later.
    dd 0x00000083
    times (KERNEL_PAGE_NUMBER - 1) dd 0                 ; Pages before kernel space.
    ; This page directory entry defines a 4MB page containing the kernel.
    dd 0x00000083
    times (1024 - KERNEL_PAGE_NUMBER - 1) dd 0  ; Pages after the kernel image.
Why is bit 7 set? Isnt that a reserved bit? Also, why in this tutorial are page tables not setup? It just sets up a directory entry and loads it, but does not map those tables to any addresses.

Re: higher half tutorial question

Posted: Sat Feb 28, 2009 11:04 am
by Hery
Bit 7 of page directory entry determines if the size of pages is 4kB or 4MB. (Volume 3A 3.7.6 of Intel manuals)
In this example bit 7 is set, so there are 4MB pages (what is mentioned in the comments above). It is also the reason why no page tables are set. They are not used when size of a page is 4MB (Volume 3A 3.7.2 of Intel manuals).

Re: higher half tutorial question

Posted: Sun Mar 01, 2009 7:15 pm
by yemista
I copied the code exactly from there, and only modified a bit for my bootloader, and I get
(physical address not available) from bochs. the only thing different is my linker script, but shouldnt it be equivalent to the one on the wiki?

Code: Select all

SECTIONS
{
	.textA 0x00000000 : { cr0.o(.cr0_text) }

	.textB (0x00100000 + SIZEOF (.textA)) : 
	  AT ( ADDR (.textA) + SIZEOF (.textA))
	{ cr1.o(.cr1_text) }

	.dataB ALIGN (0x1000) 
	 : AT ( ADDR (.textA) + SIZEOF (.textA) + SIZEOF(.textB))
	{ cr1.o(.cr1_data) }
	
	.textC (0xC0100000 + SIZEOF (.textA) + SIZEOF (.textB) + SIZEOF (.dataB)) :
	  AT (ADDR (.textA) + SIZEOF (.textA) + SIZEOF (.textB) +  SIZEOF (.dataB))
	{ *(.text) }
	.rodata : { *(.ro) }
	.data : { *(.data) }
	.bss : { *(.bss) }
}

Re: higher half tutorial question

Posted: Mon Mar 02, 2009 7:38 am
by yemista
This kind of script did work before I was trying to map my kernel to the higher half. I know it doesnt look very clean, but I need to do it this way because when cr0 runs, the offsets in the gdt are 0x00100000, and cr0 resets them to 0 and jumps to cr1, which is and thinks it is running at 0x00100000, and then that part is supposed to setup the kernel in the higher half, which is why the rest of the code is linked to run at 0xC0100000 + the size of the previous sections. I dont know why it wont work. I double checked the math and it seems fine. I have also tried using peoples code who use 4MB pages, and who use 4KB pages, with the same error, so I dont think its because my version of bochs does not support 4MB pages. I get an error right after paging is enabled.

Oh yes, I forgot to mention, I found out why it doesnt work. My tables are all screwed up. Not in the way I designed them, but in they way they got assembled. Im not sure whats going on, and my best guess is that I dont really understand how align works. I will post some code as soon as I get a chance

Re: higher half tutorial question

Posted: Mon Mar 02, 2009 6:44 pm
by yemista
Ok, here is the problem as I find it.

first, here is the code in question

Code: Select all

[section .cr1_data]

; Page table to map the first 4MB of physical memory





boot_page_directory:
    dd (0x00000003 + boot_page_table)
    times (KERNEL_DIR_NUMBER - 1) dd 0                 ; Pages before kernel space.
    ; This page directory entry defines a 4MB page containing the kernel.
    dd (0x00000003 + boot_page_table)
    times (1024 - KERNEL_DIR_NUMBER - 1) dd 0  ; Pages after the kernel image.


	
boot_page_table:
	%assign i 0
	%rep    1024
	dd (0x00000003 + (i * 4096))
	%assign i (i+1)
	%endrep
next, the relevant section of the linker script

Code: Select all

	.dataB ALIGN (0x1000) 
	 : AT ( ADDR (.textA) + SIZEOF (.textA) + SIZEOF(.textB))
	{ cr1.o(.cr1_data) }
finally, heres what bochs displays as the contents of memory where both these data structures should be stored.

Code: Select all

<bochs:3> x /10 0x00101000
[bochs]:
0x00101000 <bogus+       0>:	0x00000000	  0x00000000	0x00000000        0x00000000
0x00101010 <bogus+      16>:	0x00000000  0x00000000	0x00000000 	0x00000000
0x00101020 <bogus+      32>:	0x00000000	  0x00000000
<bochs:4> x /10 0x00102000
[bochs]:
0x00102000 <bogus+       0>:	0x0003003d	  0x1003003e	0x2003003e 	0x3003003e
0x00102010 <bogus+      16>:	0x4003003e	  0x5003003e      0x6003003e	        0x7003003e
0x00102020 <bogus+      32>:	0x8003003e	  0x9003003e
So I figured out its failing because my tables are junk, but I dont know why they are turning out like this and it appears to be the data is not aligned properly and is overwriting itself. I also tried in the nasm code to put in align 8, but this still will not produce the same results. Shouldnt align 8 make it so that every 8 bytes it will start over again? I also tried align 4 for fun and no results. Is it the align directive in the linker code changing things? This appears like a simple answer, but Im not too sure how align really works or whats going on, because the way I understood it does not appear to be correct

Re: higher half tutorial question

Posted: Fri Mar 06, 2009 11:55 am
by yemista
Does anyone have any ideas on this? I have no idea why all the entries for boot_page_directory are coming up 0, or where all the 3e's are comming from for
the boot_page_table. I am very reluctant to continue development on my kernel
because I do not want to constrict user apps by address space, and unless they
have some kernel code mapped in, they are pretty useless without system calls.

Re: higher half tutorial question

Posted: Fri Mar 06, 2009 2:31 pm
by yemista
Well results are results so Ill take a look at it, but I cant see why this wouldnt compile as it should. What doesnt make any sense is that the boot_page_table is mostly correct. The entries are as they should be except for all those "3e"'s, but the way it is coded is pretty much equivalent to the boot_page_directory, except that ends up as all zeros, and that does not make any sense.