Can't access VESA LFB without getting page fault

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
codyd51
Member
Member
Posts: 77
Joined: Fri May 20, 2016 2:29 pm
Location: London, UK
GitHub: https://github.com/codyd51
Contact:

Can't access VESA LFB without getting page fault

Post by codyd51 »

Whenever I try to write a pixel to the LFB in VESA mode, I get a page fault (page present, read). My paging implementation is from James Molloy's OS series. I've tried identity mapping the LFB as follows:

Code: Select all

for (unsigned int i = 0xFD000000; i < 0xFE000000; i += 0x1000) {
    page_t* pg = get_page(i, 1, kernel_directory);
    alloc_page(pg, 1, 1);
}
These are the prototypes for those functions:

Code: Select all

page_t* get_page(uint32_t address, int make, page_directory_t* dir);
void alloc_frame(page_t* page, int is_kernel, int is_writeable);
When paging is disabled, I'm able to write pixels to the LFB without issue.

Am I identity mapping the LFB incorrectly? Is there something else I need to do to identity map it correctly? Feel free to let me know if you need any more of the implementation. Thanks!
User avatar
BrightLight
Member
Member
Posts: 901
Joined: Sat Dec 27, 2014 9:11 am
Location: Maadi, Cairo, Egypt
Contact:

Re: Can't access VESA LFB without getting page fault

Post by BrightLight »

Do you flush caches after modifying the page tables? Use INVLPG instruction, or simply do:

Code: Select all

mov rax, cr3
mov cr3, rax
What error code does your page fault have?
You know your OS is advanced when you stop using the Intel programming guide as a reference.
User avatar
max
Member
Member
Posts: 616
Joined: Mon Mar 05, 2012 11:23 am
Libera.chat IRC: maxdev
Location: Germany
Contact:

Re: Can't access VESA LFB without getting page fault

Post by max »

Invalidating might help as omar said, but to tell you for sure you'd have to show us what the functions you call there do.
codyd51
Member
Member
Posts: 77
Joined: Fri May 20, 2016 2:29 pm
Location: London, UK
GitHub: https://github.com/codyd51
Contact:

Re: Can't access VESA LFB without getting page fault

Post by codyd51 »

The page fault still happens even after flushing the cache :/ error code 2.

Here's the implementation of those two functions:

Code: Select all

page_t* get_page(uint32_t address, int make, page_directory_t* dir) {
	//turn address into an index
	address /= 0x1000;
	//find page table containing this address
	uint32_t table_idx = address / 1024;

	//if this page is already assigned
	if (dir->tables[table_idx]) {
		return &dir->tables[table_idx]->pages[address%1024];
	}
	else if (make) {
		uint32_t tmp;
		dir->tables[table_idx] = (page_table_t*)kmalloc_ap(sizeof(page_table_t), &tmp);
		memset(dir->tables[table_idx], 0, 0x1000);
		//PRESENT, RW, US
		dir->tablesPhysical[table_idx] = tmp | 0x7;
		return &dir->tables[table_idx]->pages[address%1024];
	}
	return 0;
}

void alloc_frame(page_t* page, int is_kernel, int is_writeable) {
	if (page->frame != 0) {
		//frame was already allocated, return early
		return;
	}
	uint32_t idx = first_frame(); //index of first free frame
	if (idx == (uint32_t)-1) {
		PANIC("No free frames!");
	}
	set_frame(idx*0x1000); //frame is now ours
	page->present = 1; //mark as present
	page->rw = (is_writeable) ? 1 : 0; //should page be writable?
	page->user = (is_kernel) ? 0 : 1; //should page be user mode?
	page->frame = idx;
}
codyd51
Member
Member
Posts: 77
Joined: Fri May 20, 2016 2:29 pm
Location: London, UK
GitHub: https://github.com/codyd51
Contact:

Re: Can't access VESA LFB without getting page fault

Post by codyd51 »

If I mov the regs in the order from omarrx024's comment, the page fault still occurs. If I use the order listed on http://wiki.osdev.org/TLB, it triple faults.
User avatar
BrightLight
Member
Member
Posts: 901
Joined: Sat Dec 27, 2014 9:11 am
Location: Maadi, Cairo, Egypt
Contact:

Re: Can't access VESA LFB without getting page fault

Post by BrightLight »

codyd51 wrote:If I mov the regs in the order from omarrx024's comment, the page fault still occurs. If I use the order listed on http://wiki.osdev.org/TLB, it triple faults.
In the TLB Wiki page, it is in GAS syntax, not Intel syntax. The code there is the same as my code but in different syntax. ;)
Error code 2 says that the kernel tried to write to a non-present page. So either your page directory or your page table entry doesn't has the present bit set.
You know your OS is advanced when you stop using the Intel programming guide as a reference.
codyd51
Member
Member
Posts: 77
Joined: Fri May 20, 2016 2:29 pm
Location: London, UK
GitHub: https://github.com/codyd51
Contact:

Re: Can't access VESA LFB without getting page fault

Post by codyd51 »

omarrx024 wrote:
codyd51 wrote:If I mov the regs in the order from omarrx024's comment, the page fault still occurs. If I use the order listed on http://wiki.osdev.org/TLB, it triple faults.
In the TLB Wiki page, it is in GAS syntax, not Intel syntax. The code there is the same as my code but in different syntax. ;)
Error code 2 says that the kernel tried to write to a non-present page. So either your page directory or your page table entry doesn't has the present bit set.
Whoops! Silly me :P

I finally figured it out, I call the following function in my init_paging function. Not totally sure why it doesn't work after paging is already enabled and flushing the TLB cache, but oh well:

Code: Select all

#define VESA_WIDTH 1024
#define VESA_HEIGHT 768
void identity_map_lfb(uint32_t location) {
	uint32_t j = location;
	while (j < location + (VESA_WIDTH * VESA_HEIGHT * 4)) {
		//if frame is valid
		if (j + location + (VESA_WIDTH * VESA_HEIGHT * 4) < memsize) {
			set_frame(j); //tell frame bitset this frame is in use
		}
		//get page
		page_t* page = get_page(j, 1, kernel_directory);
		//fill it
		page->present = 1;
		page->rw = 1;
		page->user = 1;
		page->frame = j / 0x1000;
		j += 0x1000;
	}
}
And it'd be called with:
identity_map_lfb(your_vesa_mode_info->physbase);
I hope this helps someone having the same problem!
Post Reply