higher half tutorial question

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
User avatar
yemista
Member
Member
Posts: 299
Joined: Fri Dec 26, 2008 12:31 pm
Location: Boston
Contact:

higher half tutorial question

Post 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.
Hery
Member
Member
Posts: 65
Joined: Sat Dec 04, 2004 12:00 am

Re: higher half tutorial question

Post 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).
User avatar
yemista
Member
Member
Posts: 299
Joined: Fri Dec 26, 2008 12:31 pm
Location: Boston
Contact:

Re: higher half tutorial question

Post 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) }
}
User avatar
yemista
Member
Member
Posts: 299
Joined: Fri Dec 26, 2008 12:31 pm
Location: Boston
Contact:

Re: higher half tutorial question

Post 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
User avatar
yemista
Member
Member
Posts: 299
Joined: Fri Dec 26, 2008 12:31 pm
Location: Boston
Contact:

Re: higher half tutorial question

Post 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
User avatar
yemista
Member
Member
Posts: 299
Joined: Fri Dec 26, 2008 12:31 pm
Location: Boston
Contact:

Re: higher half tutorial question

Post 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.
User avatar
yemista
Member
Member
Posts: 299
Joined: Fri Dec 26, 2008 12:31 pm
Location: Boston
Contact:

Re: higher half tutorial question

Post 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.
Post Reply