How to make a GDT?

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.
zap8600
Member
Member
Posts: 195
Joined: Tue Nov 02, 2021 11:26 am
Libera.chat IRC: zap8600

Re: How to make a GDT?

Post by zap8600 »

Octocontrabass wrote: Limine provides direct access to all memory with either identity mapping or a fixed offset in the higher half. If you're not going to use paging, you can use one of these ranges to access memory and you won't have any page faults unless there's a problem with your code.

How does your OS manage memory without using paging? That's a very unusual design choice.
I'm using this simple bitmap heap implementation. I'm dumb, so I went with a simple option, one I can understand.
Octocontrabass wrote: If you want to set up your own paging structures, you would probably need to create all four levels from scratch. In theory you could use Limine's paging structures, but Limine doesn't make any promises about their contents beyond the attributes and address ranges. (Paging structures have 4096-byte alignment.)
Which one is recommended?
Octocontrabass
Member
Member
Posts: 5560
Joined: Mon Mar 25, 2013 7:01 pm

Re: How to make a GDT?

Post by Octocontrabass »

zap8600 wrote:I'm using this simple bitmap heap implementation. I'm dumb, so I went with a simple option, one I can understand.
That code should never cause page faults. Either you're using it incorrectly or you've found a bug.

It's also not a complete memory manager. You still need some way to keep track of which physical memory is available; userspace won't be able to use the kernel heap.
zap8600 wrote:Which one is recommended?
Setting up your own four-level page structures from scratch. You'll need to do that at some point, unless your OS is meant to follow a very non-traditional design.
zap8600
Member
Member
Posts: 195
Joined: Tue Nov 02, 2021 11:26 am
Libera.chat IRC: zap8600

Re: How to make a GDT?

Post by zap8600 »

Octocontrabass wrote: That code should never cause page faults. Either you're using it incorrectly or you've found a bug.

It's also not a complete memory manager. You still need some way to keep track of which physical memory is available; userspace won't be able to use the kernel heap.
The page fault happens when I add a block. The starting address is _kernel_end, which is defined in my linker script.
Octocontrabass wrote: Setting up your own four-level page structures from scratch. You'll need to do that at some point, unless your OS is meant to follow a very non-traditional design.
I guess I'll do this. Is setting up paging while in long mode any different than setting up paging while in protected mode? I guess I'll also figure out how to make a decent memory manager.
Octocontrabass
Member
Member
Posts: 5560
Joined: Mon Mar 25, 2013 7:01 pm

Re: How to make a GDT?

Post by Octocontrabass »

zap8600 wrote:The page fault happens when I add a block. The starting address is _kernel_end, which is defined in my linker script.
Limine doesn't map any memory at that address. Either use the memory map provided by Limine to find some available memory or set up your physical and virtual memory managers before you set up your heap.
zap8600 wrote:Is setting up paging while in long mode any different than setting up paging while in protected mode?
Paging is already enabled, so you just need to set up the structures somewhere in memory and update CR3 to point to your structures instead of Limine's structures.
zap8600
Member
Member
Posts: 195
Joined: Tue Nov 02, 2021 11:26 am
Libera.chat IRC: zap8600

Re: How to make a GDT?

Post by zap8600 »

Octocontrabass wrote: Limine doesn't map any memory at that address. Either use the memory map provided by Limine to find some available memory or set up your physical and virtual memory managers before you set up your heap.

Paging is already enabled, so you just need to set up the structures somewhere in memory and update CR3 to point to your structures instead of Limine's structures.
I think I'll just use Limine's memory map. Does the PMM make pages or does it just allocate memory?
Octocontrabass
Member
Member
Posts: 5560
Joined: Mon Mar 25, 2013 7:01 pm

Re: How to make a GDT?

Post by Octocontrabass »

The PMM only allocates physical memory, it doesn't touch the paging structures.
zap8600
Member
Member
Posts: 195
Joined: Tue Nov 02, 2021 11:26 am
Libera.chat IRC: zap8600

Re: How to make a GDT?

Post by zap8600 »

I am now less of an idiot than I once was. I understand how my memory managing system needs to work. The simple bitmap heap implementation I am using allocates virtual memory for the heap. In order to use the memory after the kernel's end, I will need to create a new page table entry. Is this correct?
Octocontrabass
Member
Member
Posts: 5560
Joined: Mon Mar 25, 2013 7:01 pm

Re: How to make a GDT?

Post by Octocontrabass »

There is no memory after the kernel's end until you create a new page table entry.

Why does your heap need to go there? Limine has already mapped all physical memory to virtual addresses.
zap8600
Member
Member
Posts: 195
Joined: Tue Nov 02, 2021 11:26 am
Libera.chat IRC: zap8600

Re: How to make a GDT?

Post by zap8600 »

Before I continue trying to get a memory manager working, I'm going to switch to using the Multiboot protocol so that my OS can be booted by a variety of bootloaders.
Octocontrabass
Member
Member
Posts: 5560
Joined: Mon Mar 25, 2013 7:01 pm

Re: How to make a GDT?

Post by Octocontrabass »

Multiboot loads your OS in protected mode, not long mode, so you'll need additional code to switch to long mode.
kzinti
Member
Member
Posts: 898
Joined: Mon Feb 02, 2015 7:11 pm

Re: How to make a GDT?

Post by kzinti »

Switching bootloader is only going to slow you down. But if you like writing bootloaders more than kernels, go for it.
zap8600
Member
Member
Posts: 195
Joined: Tue Nov 02, 2021 11:26 am
Libera.chat IRC: zap8600

Re: How to make a GDT?

Post by zap8600 »

kzinti wrote:Switching bootloader is only going to slow you down. But if you like writing bootloaders more than kernels, go for it.
I'm not switching bootloaders; I'm just switching boot protocols. It also allows me to use my OS with multiple bootloaders.

How do I make a framebuffer with multiboot?
User avatar
iansjack
Member
Member
Posts: 4703
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: How to make a GDT?

Post by iansjack »

Have you read the multiboot specifications?

https://www.gnu.org/software/grub/manua ... iboot.html
zap8600
Member
Member
Posts: 195
Joined: Tue Nov 02, 2021 11:26 am
Libera.chat IRC: zap8600

Re: How to make a GDT?

Post by zap8600 »

iansjack wrote:Have you read the multiboot specifications?

https://www.gnu.org/software/grub/manua ... iboot.html
Thanks. I guess I should ask how to jump to long mode from my boot.S file first.
How do I do that? I think I can use something similar to this.
zap8600
Member
Member
Posts: 195
Joined: Tue Nov 02, 2021 11:26 am
Libera.chat IRC: zap8600

Re: How to make a GDT?

Post by zap8600 »

Would something like the following be good for a multiboot boot.S file?

Code: Select all

/* Multiboot 1 header */
.set MB_MAGIC,              0x1BADB002
.set MB_FLAG_PAGE_ALIGN,    1 << 0
.set MB_FLAG_MEMORY_INFO,   1 << 1
.set MB_FLAG_GRAPHICS,      1 << 2
.set MB_FLAG_AOUT,          1 << 16
.set MB_FLAGS,              MB_FLAG_PAGE_ALIGN | MB_FLAG_MEMORY_INFO
.set MB_CHECKSUM,           -(MB_MAGIC + MB_FLAGS)

/* Multiboot section */
.section .multiboot
.code32

.align 4
multiboot_header:
.long MB_MAGIC
.long MB_FLAGS
.long MB_CHECKSUM
.long multiboot_header /* header_addr */
.long phys             /* load_addr */
.long bss_start        /* load_end_addr */
.long end              /* bss_end_addr */
.long _start

/* Request linear graphics mode */
.long 0x00000000
.long 1024
.long 768
.long 32

.section .stack, "aw", @nobits
stack_bottom:
.skip 16384 /* 16KiB */
.global stack_top
stack_top:

.section .bootstrap
.code32
.align 4

.extern jmp_to_long
.type jmp_to_long, @function

.extern kernel_main
.type kernel_main, @function

.global _start
.type _start, @function

_start:
    /* Setup our stack */
    mov $stack_top, %esp

    /* Make sure our stack is 16-byte aligned */
    and $-16, %esp

    pushl $0
    pushl %esp
    pushl $0
    pushl %eax /* Multiboot header magic */
    pushl $0
    pushl %ebx /* Multiboot header pointer */

    jmp jmp_to_long


.align 4

jmp_to_long:
    /* Set up initial page region, which was zero'd for us by the loader */
    mov $0x1000, %edi
    mov %edi, %cr3

    /* PML4[0] = &PDP[0] | (PRESENT, WRITABLE, USER) */
    mov $0x1007, %eax
    add %edi, %eax
    mov %eax, (%edi)

    /* PDP[0] = &PD[0] | (PRESENT, WRITABLE, USER) */
    add $0x1000, %edi
    mov $0x1003, %eax
    add %edi, %eax
    mov %eax, (%edi)

    /* Set 32 2MiB pages to map 64MiB of low memory temporarily, which should
       be enough to get us through our C MMU initialization where we then
       use 2MiB pages to map all of the 4GiB standard memory space and map
       a much more restricted subset of the kernel in the lower address space. */
    add $0x1000, %edi

    mov $0x87, %ebx
    mov $32, %ecx

.set_entry:
    mov %ebx, (%edi)
    add $0x200000, %ebx
    add $8, %edi
    loop .set_entry

    /* Enable PAE */
    mov %cr4, %eax
    or $32, %eax
    mov %eax, %cr4

    /* EFER */
    mov $0xC0000080, %ecx
    rdmsr
    or $256, %eax
    wrmsr

    /* Set PG */
    mov %cr0, %eax
    or $0x80000000, %eax
    mov %eax, %cr0

    lgdt gdtr
    ljmp $0x08,$realm64

.align 8
gdtr:
    .word gdt_end-gdt_base
    .quad gdt_base

gdt_base:
    /* Null */
    .quad 0
    /* Code */
    .word 0
    .word 0
    .byte 0
    .byte 0x9a
    .byte 0x20
    .byte 0
    /*  Data */
    .word 0xffff
    .word 0
    .byte 0
    .byte 0x92
    .byte 0
    .byte 0
gdt_end:


.code64
.align 8
.section .bootstrap

realm64:
    cli
    mov $0x10, %ax
    mov %ax, %ds
    mov %ax, %es
    mov %ax, %fs
    mov %ax, %gs
    mov %ax, %ss

    pop %rdi
    pop %rsi
    pop %rdx
    callq kernel_main

halt:
    cli
    hlt
    jmp halt
Post Reply