I have bootstraped my kernel in longmode.
I am using multiboot version 1 with grub and I enabled the video flag.
I added the page where the framebuffer is to the page tables.
I passed the multiboot struct address to my C kernel.
From there I am trying to write to the framebuffer address but my kernel panics in qemu.
Also when I print the framebuffer address in gdb it says it cannot access the memory.
Code:
(gdb) print fb
$2 = 0xfd000000 <error: Cannot access memory at address 0xfd000000>
The code that I use to add the framebuffer page tables is:
Code:
setup_framebuffer_page_tables:
/* Get the multiboot struct address */
movl %ebx, %edx
/*
Offset to the framebuffer member. The offset of the framebuffer member is
actually 84 and it size is 64 bits, but since we are currently in protected
mode, the address cannot be bigger than 32 bits.
*/
add $88, %edx
movl (%edx), %edx
/* L4 */
movl %edx, %ecx
shr $30, %ecx
and $0b111111111, %ecx
movl $page_table_l3_framebuffer, %eax
orl $0b11, %eax
movl %eax, page_table_l4(, %ecx, 8)
/* L3 */
movl %edx, %ecx
shr $21, %ecx
and $0b111111111, %ecx
movl $page_table_l2_framebuffer, %eax
orl $0b11, %eax
movl %eax, page_table_l3_framebuffer(, %ecx, 8)
/* Huge pages of size 2 MiBs */
movl $0, %ecx
.loop2:
movl $0x200000, %eax
mul %ecx
/* present, writable, hugepage */
orl $0b10000011, %eax
movl %eax, page_table_l2_framebuffer(, %ecx, 8)
inc %ecx
cmp $512, %ecx
jne .loop2
ret
I debugged the code and it seemed liked its adding the pages correctly, but I am not sure if I should also do something more, like edit the gdt64.
Essentially what I want is to have a working console as soon as possible in long mode.