I tried to do this:
Code: Select all
for(uint32_t i = vbe_buff; i < vbe_buff + vbe_height * vbe_width * (vbe_bpp / 8); i++)
{
page_table[i] = (i * 0x1000) | 0b111;
}
Code: Select all
for(uint32_t i = vbe_buff; i < vbe_buff + vbe_height * vbe_width * (vbe_bpp / 8); i++)
{
page_table[i] = (i * 0x1000) | 0b111;
}
Here's the log:Ch4ozz wrote:Start your QEMU with -d int,cpu_reset and it will create a log file telling you why it tripple faults.
A tripple fault happens when the first exception couldnt get handled, so it will send it again.
If the second exception cant be handled either it will tripplefault and reset the CPU.
Make sure you mapped your whole kernel code.
Code: Select all
CPU Reset (CPU 0)
EAX=00000000 EBX=00000000 ECX=00000000 EDX=00000000
ESI=00000000 EDI=00000000 EBP=00000000 ESP=00000000
EIP=00000000 EFL=00000000 [-------] CPL=0 II=0 A20=0 SMM=0 HLT=0
ES =0000 00000000 00000000 00000000
CS =0000 00000000 00000000 00000000
SS =0000 00000000 00000000 00000000
DS =0000 00000000 00000000 00000000
FS =0000 00000000 00000000 00000000
GS =0000 00000000 00000000 00000000
LDT=0000 00000000 00000000 00000000
TR =0000 00000000 00000000 00000000
GDT= 00000000 00000000
IDT= 00000000 00000000
CR0=00000000 CR2=00000000 CR3=00000000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000
DR6=00000000 DR7=00000000
CCS=00000000 CCD=00000000 CCO=DYNAMIC
EFER=0000000000000000
FCW=0000 FSW=0000 [ST=0] FTW=ff MXCSR=00000000
FPR0=0000000000000000 0000 FPR1=0000000000000000 0000
FPR2=0000000000000000 0000 FPR3=0000000000000000 0000
FPR4=0000000000000000 0000 FPR5=0000000000000000 0000
FPR6=0000000000000000 0000 FPR7=0000000000000000 0000
XMM00=00000000000000000000000000000000 XMM01=00000000000000000000000000000000
XMM02=00000000000000000000000000000000 XMM03=00000000000000000000000000000000
XMM04=00000000000000000000000000000000 XMM05=00000000000000000000000000000000
XMM06=00000000000000000000000000000000 XMM07=00000000000000000000000000000000
CPU Reset (CPU 0)
EAX=00000000 EBX=00000000 ECX=00000000 EDX=00000663
ESI=00000000 EDI=00000000 EBP=00000000 ESP=00000000
EIP=0000fff0 EFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0000 00000000 0000ffff 00009300
CS =f000 ffff0000 0000ffff 00009b00
SS =0000 00000000 0000ffff 00009300
DS =0000 00000000 0000ffff 00009300
FS =0000 00000000 0000ffff 00009300
GS =0000 00000000 0000ffff 00009300
LDT=0000 00000000 0000ffff 00008200
TR =0000 00000000 0000ffff 00008b00
GDT= 00000000 0000ffff
IDT= 00000000 0000ffff
CR0=60000010 CR2=00000000 CR3=00000000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000
DR6=ffff0ff0 DR7=00000400
CCS=00000000 CCD=00000000 CCO=DYNAMIC
EFER=0000000000000000
FCW=037f FSW=0000 [ST=0] FTW=00 MXCSR=00001f80
FPR0=0000000000000000 0000 FPR1=0000000000000000 0000
FPR2=0000000000000000 0000 FPR3=0000000000000000 0000
FPR4=0000000000000000 0000 FPR5=0000000000000000 0000
FPR6=0000000000000000 0000 FPR7=0000000000000000 0000
XMM00=00000000000000000000000000000000 XMM01=00000000000000000000000000000000
XMM02=00000000000000000000000000000000 XMM03=00000000000000000000000000000000
XMM04=00000000000000000000000000000000 XMM05=00000000000000000000000000000000
XMM06=00000000000000000000000000000000 XMM07=00000000000000000000000000000000
SMM: enter
EAX=00000001 EBX=0000000b ECX=02000000 EDX=00000cfc
ESI=00000000 EDI=02000000 EBP=00000000 ESP=00006d20
EIP=000f14f5 EFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
CS =0008 00000000 ffffffff 00cf9b00 DPL=0 CS32 [-RA]
SS =0010 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
DS =0010 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
FS =0010 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
GS =0010 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS32-busy
GDT= 000f6be8 00000037
IDT= 000f6c26 00000000
CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000
DR6=ffff0ff0 DR7=00000400
CCS=000f1030 CCD=00000001 CCO=LOGICB
EFER=0000000000000000
SMM: after RSM
EAX=00000001 EBX=0000000b ECX=02000000 EDX=00000cfc
ESI=00000000 EDI=02000000 EBP=00000000 ESP=00006d20
EIP=000f14f5 EFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 00000000 ffffffff 00c09300 DPL=0 DS [-WA]
CS =0008 00000000 ffffffff 00c09b00 DPL=0 CS32 [-RA]
SS =0010 00000000 ffffffff 00c09300 DPL=0 DS [-WA]
DS =0010 00000000 ffffffff 00c09300 DPL=0 DS [-WA]
FS =0010 00000000 ffffffff 00c09300 DPL=0 DS [-WA]
GS =0010 00000000 ffffffff 00c09300 DPL=0 DS [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS32-busy
GDT= 000f6be8 00000037
IDT= 000f6c26 00000000
CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000
DR6=ffff0ff0 DR7=00000400
CCS=00000000 CCD=ffffff9c CCO=EFLAGS
EFER=0000000000000000
Code: Select all
vbe_height * vbe_width * (vbe_bpp / 8) / 4096
Thank you for reply. Here's the definitions of vbe stuff:sleephacker wrote:It looks like you're treating every single byte in the framebuffer as a page. The number of pages should be the number of bytes / 4096. In your case this should be:Also, what is vbe_buff? I assume it is the physical address of the framebuffer, in that case you shouldn't multiply by 0x1000 to calculate the physical address, because it already is the physical address, and to calculate the index in your page table you should divide it by 0x1000 (or 4096) instead of leaving it unchanged.Code: Select all
vbe_height * vbe_width * (vbe_bpp / 8) / 4096
Code: Select all
uint32_t vbe_width, vbe_height, vbe_bpp, vbe_pitch;
uint8_t* vbe_buff;
Code: Select all
for(uint32_t i = vbe_buff; i < vbe_buff + vbe_height * vbe_width * (vbe_bpp / 8) / 4096; i++)
{
page_table[i] = i | 1 | 2 | 4;
}
If you want "i" to initially be the first page of the framebuffer, you should do:Askodem wrote:I tried the following code:But it still triple faulting.Code: Select all
for(uint32_t i = vbe_buff; i < vbe_buff + vbe_height * vbe_width * (vbe_bpp / 8) / 4096; i++) { page_table[i] = i | 1 | 2 | 4; }
Code: Select all
i = vbe_buff / 0x1000
Code: Select all
page_table[i] = i *0x1000 | 1 | 2 | 4;
Code: Select all
vbe_buff_size = vbe_height * vbe_width * (vbe_bpp / 8)
vbe_first_page = vbe_buff / 0x1000
vbe_page_count = vbe_buff_size / 0x1000
Code: Select all
for(i = vbe_first_page; i < vbe_first_page + vbe_page_count; i++)
{
page_table[i] = i * 0x1000 | 7; //7 == 1 | 2 | 4
}
Code: Select all
vbe_buff_size = vbe_height * BytesPerScanLine
Code: Select all
vbe_pitch = multiboot->framebuffer_pitch;
Code: Select all
extern void switch_page_dir(uint32_t*);
extern void enable_paging();
uint32_t page_directory[1024] __attribute__((aligned(4096)));
uint32_t page_table[1024] __attribute__((aligned(4096)));
void init_paging()
{
uint32_t vbe_buff_size = vbe_height * vbe_width * (vbe_bpp / 8) * vbe_pitch;
uint32_t vbe_first_page = (int)vbe_buff / 0x1000;
uint32_t vbe_page_count = vbe_buff_size / 0x1000;
for(int i = 0; i < 1024; i++)
{
page_directory[i] = 0x00000002;
}
for(uint32_t i = 0; i < 1024; i++)
{
page_table[i] = (i * 0x1000) | 3;
}
for(uint32_t i = vbe_first_page; i < vbe_first_page + vbe_page_count; i++)
{
page_table[i] = i * 0x1000 | 7; //7 == 1 | 2 | 4
}
page_directory[0] = ((uint32_t)page_table) | 3;
switch_page_dir(page_directory);
enable_paging();
}
yepAskodem wrote:BytesPerScanLine == vbe_pitch, right?
I created 1024 page tables(4096 * 1024 = 4194304 = 4 GB):sleephacker wrote:yepAskodem wrote:BytesPerScanLine == vbe_pitch, right?
One issue with this code is the fact that you only have one page table, meaning you can only identity-map the lowest 4MB of memory, while your framebuffer is likely to be located elsewhere.
So you need to be able to map all 4GB (assuming you're using a 32bit address space) in order to map your framebuffer.
Code: Select all
uint32_t page_table[1024][1024] __attribute__((aligned(4096)));
Code: Select all
extern void switch_page_dir(uint32_t*);
extern void enable_paging();
uint32_t page_directory[1024] __attribute__((aligned(4096)));
uint32_t page_table[1024][1024] __attribute__((aligned(4096)));
void init_paging()
{
uint32_t vbe_buff_size = vbe_height * vbe_width * (vbe_bpp / 8) * vbe_pitch;
uint32_t vbe_first_page = (int)vbe_buff / 0x1000;
uint32_t vbe_page_count = vbe_buff_size / 0x1000;
for(int i = 0; i < 1024; i++)
page_directory[i] = 0x00000002;
for(uint32_t i = 0; i < 1024; i++)
for(uint32_t j = 0; j < 1024; j++)
page_table[i][j] = (i * 0x1000) | 3;
for(uint32_t i = vbe_first_page; i < vbe_first_page + vbe_page_count; i++)
{
page_table[0][i] = i * 0x1000 | 7; //7 == 1 | 2 | 4
}
for(int i = 0; i < 1024; i++)
page_directory[i] = ((uint32_t)page_table[i]) | 3;
switch_page_dir(page_directory);
enable_paging();
}
That means that the mode has been set successfully, just to make sure compare Qemu's screen size after and before switching.Askodem wrote: Qemu no more restarts. It's just black screen.
It doesn't works. I have the working VBE shell. It works without paging.octacone wrote:That means that the mode has been set successfully, just to make sure compare Qemu's screen size after and before switching.Askodem wrote: Qemu no more restarts. It's just black screen.
Try putting some pixels and see if that works (just don't put black ones because you won't be able to see them )
Wait, what doesn't work? Your shell or setting mode?Askodem wrote:It doesn't works. I have the working VBE shell. It works without paging.octacone wrote:That means that the mode has been set successfully, just to make sure compare Qemu's screen size after and before switching.Askodem wrote: Qemu no more restarts. It's just black screen.
Try putting some pixels and see if that works (just don't put black ones because you won't be able to see them )
All of the above works. Screen resolution changes, but i have black screen.Wait, what doesn't work? Your shell or setting mode?
Code: Select all
for(uint32_t i = 0; i < 1024; i++)
for(uint32_t j = 0; j < 1024; j++)
page_table[i][j] = (i * 0x1000) | 3;
Code: Select all
for(uint32_t i = 0; i < 1024; i++)
for(uint32_t j = 0; j < 1024; j++)
page_table[i][j] = ((i * 1024 + j) * 0x1000) | 3;
Code: Select all
printf("Before enabling paging:\n");
printf("The first 4 entries in the page directory:\n");
for(int i = 0; i < 4; i++)
printf("Hex: 0x%h, Dec: %d\n", page_directory[i], page_directory[i]);
printf("\nthe first 4 entries in the first page table\n");
for(int i = 0; i < 4; i++)
printf("Hex: 0x%h, Dec: %d\n", page_table[0][i], page_table[0][i]);
printf("\nthe first 4 entries after vbe_first_page:\n");
for(uint32_t i = vbe_first_page; i < vbe_first_page + 4; i++)
printf("Hex: 0x%h, Dec: %d\n", page_table[0][i], page_table[0][i]);
switch_page_dir(page_directory);
enable_paging();
printf("\nAfter enabling paging:\n\n");
printf("The first 4 entries in the page directory:\n");
for(int i = 0; i < 4; i++)
printf("Hex: 0x%h, Dec: %d\n", page_directory[i], page_directory[i]);
printf("\nthe first 4 entries in the first page table\n");
for(int i = 0; i < 4; i++)
printf("Hex: 0x%h, Dec: %d\n", page_table[0][i], page_table[0][i]);
printf("\nthe first 4 entries after vbe_first_page:\n");
for(uint32_t i = vbe_first_page; i < vbe_first_page + 4; i++)
printf("Hex: 0x%h, Dec: %d\n", page_table[0][i], page_table[0][i]);