Page 3 of 3

Posted: Sun Mar 16, 2008 12:56 am
by jzgriffin
No luck. I tried removing &, and rewriting the function in Assembly (then trying with and without &). Any more ideas...?

Posted: Sun Mar 16, 2008 1:15 am
by Stevo14
I had a similar problem come up when using James' tutorials. It turns out that the problem is solved in the download-able version of the code.

Change this:

Code: Select all

 int idx = 0;
   while (idx < placement_address) {
      /* Kernel code is readable but not writeable from userspace */
      allocate_frame(get_page(idx, 1, kernel_directory), 0, 0);
      idx += 0x1000;
   } 
To this:

Code: Select all

int idx = 0;
   while (idx < placement_address + 0x1000) {
      /* Kernel code is readable but not writeable from userspace */
      allocate_frame(get_page(idx, 1, kernel_directory), 0, 0);
      idx += 0x1000;
   } 
The extra 0x1000 is needed, probably because the kernel "leaks" slightly over the last page boundary. (the 0x1000 simply "rounds up" the number of pages so that you are guaranteed to have enough pages.)

Posted: Sun Mar 16, 2008 1:17 am
by jzgriffin
My code does use the downloadable version. "+ 0x1000" is there.

Posted: Sun Mar 16, 2008 1:27 am
by Stevo14
Ah, ok. I was looking at the code that you posted in the first post. Sorry.

Posted: Sun Mar 16, 2008 1:32 am
by jzgriffin
Nah, it's fine. I posted a link to the web-viewer for my Subversion repository. Thanks for the suggestion, though. :-)

Posted: Sun Mar 16, 2008 5:19 am
by zaleschiemilgabriel
The last thing I can think of is that you're not using valid memory space and your table's contents are all 0xFF'ed up even after you write to them (allusion intended).

Posted: Sun Mar 16, 2008 10:00 am
by gzaloprgm
Jeremiah, this must work with your kernel.

Code: Select all

unsigned long *page_directory;
unsigned long *page_table;

void map(unsigned int frame, unsigned int vframe){
	page_table[frame] = vframe*4096 | 3;
}

int init_paging(){
	page_directory = (unsigned long *) kmalloc_a(4096);
	page_table = (unsigned long *) kmalloc_a(4096);

	unsigned int i;
	for(i=0; i<1024; i++){
		map(i,i);
	};		

	page_directory[0] = (unsigned long)page_table;
	page_directory[0] = page_directory[0] | 3;

	for(i=1; i<1024; i++){
		page_directory[i] = 0 | 2;
	};

	write_cr3(page_directory);
	write_cr0(read_cr0() | 0x80000000);
	return 0;
}

Code: Select all

[global read_cr0]
read_cr0:
	mov eax, cr0
	retn

[global write_cr0]
write_cr0:
	push ebp
	mov ebp, esp
	mov eax, [ebp+8]
	mov cr0,  eax
	pop ebp
	retn

[global write_cr3]
write_cr3:
	push ebp
	mov ebp, esp
	mov eax, [ebp+8]
	mov cr3, eax
	pop ebp
	retn

That function (from osdever) works in my kernel and maps 0-4MB virtual to 0-4MB physical.

Hope it helps to you.

Gonzalo