Page 15 of 20

Re: How to make a GDT?

Posted: Sun Oct 30, 2022 10:53 am
by zap8600
devc1 wrote:I looked in to limines github repo and It seems that limines GDT 32 bit. And you are trying to run 64 bit code in 32 bit mode ? If yes and the kernel loads perfectly into the startup function, I can help you but you will not be able to use the terminal, otherwise you can just create your own terminal.

When you create a kernel, you are nomore dependent of bootloader stuff, the bootloader passed the initdata, now its your turn to startup the OS (a long trip).
I was able to use the Limine terminal in my 64-bit OS, though. If I have to, I'll use the Multiboot protocol, but I wouldn't like to if I don't have to.

Re: How to make a GDT?

Posted: Sun Oct 30, 2022 1:54 pm
by zap8600
So is there a reason why my GDT isn't working?

Re: How to make a GDT?

Posted: Sun Oct 30, 2022 3:53 pm
by Octocontrabass
devc1 wrote:Yeahhh, I am not a fan of reading btw.
OS development requires lots of reading. Perhaps you should choose a different hobby.
zap8600 wrote:So is there a reason why my GDT isn't working?
I don't see any obvious problems. Try using your debugger to examine the memory contents at the address your GDTR points to.

Re: How to make a GDT?

Posted: Sun Oct 30, 2022 3:56 pm
by devc1
Has anyone ever using limine here ?

Re: How to make a GDT?

Posted: Sun Oct 30, 2022 4:03 pm
by devc1
OS development requires lots of reading. Perhaps you should choose a different hobby.
Of course, I mainly read if I have to solve my own problems or problems that I know I will face later. Otherwise, I don't see myself reading the whole limine documentation because I'll never use it, as you've already seen in my github repo, All the programs are written from scratch with no included libraries.

I don't recommend any begineer to start with a premade bootloader, to learn he should start from scratch and discover things from the root of the tree, not from the middle.

Re: How to make a GDT?

Posted: Sun Oct 30, 2022 4:20 pm
by nexos
devc1 wrote:I don't recommend any begineer to start with a premade bootloader
No. It's best for a beginner to skip the headache of the bootloader stage and start working on stuff that will actually motivate them.
devc1 wrote:Otherwise, I don't see myself reading the whole limine documentation because I'll never use it
In that case, don't post about subjects you aren't very familiar with, and potentially mislead someone. I'm telling you this from experience :wink:

Re: How to make a GDT?

Posted: Mon Oct 31, 2022 12:35 am
by iansjack
Why stop at the boot loader? I recommend beginners to write their own BIOS. Best to start at the root of the tree. :lol:

Hardcore enthusiasts would recommend writing your own microcode.

Re: How to make a GDT?

Posted: Mon Oct 31, 2022 2:46 am
by nullplan
iansjack wrote:Why stop at the boot loader? I recommend beginners to write their own BIOS. Best to start at the root of the tree. :lol:

Hardcore enthusiasts would recommend writing your own microcode.
Invent your own CPU, build it from discrete components. Next step: Use uranium to cause bit flips in RAM precisely in such a way as to write whatever program you wanted in there.

In case anyone wonders what my sincere opinion is: The kernel is the important thing, everything else is just getting the machine ready for the kernel. Build the kernel!

Re: How to make a GDT?

Posted: Mon Oct 31, 2022 2:51 am
by iansjack
nullplan wrote:Invent your own CPU, build it from discrete components.
That's actually quite a fun exercise (the designing, not the building). It's even the basis of a computer game or two.

But I agree with you. Before the kernel it's just building blocks that teach you very little (other than how to write a boot loader). The interesting stuff starts once your kernel is loaded.

Re: How to make a GDT?

Posted: Mon Oct 31, 2022 12:13 pm
by zap8600
Octocontrabass wrote: I don't see any obvious problems. Try using your debugger to examine the memory contents at the address your GDTR points to.
Is there any way I could set up my own framebuffer from my OS? I could use Limine's framebuffer, but I'm not sure how I would print to it.

Re: How to make a GDT?

Posted: Mon Oct 31, 2022 12:45 pm
by Octocontrabass
zap8600 wrote:Is there any way I could set up my own framebuffer from my OS?
In theory yes, but in practice probably not. You would need a driver for the display adapter, and each display adapter requires a different driver.
zap8600 wrote:I could use Limine's framebuffer, but I'm not sure how I would print to it.
It's a bitmap. You plot pixels on it the same way you plot pixels in any bitmap.

Is there any particular reason why you don't want to use a debugger to check your GDT?

Re: How to make a GDT?

Posted: Mon Oct 31, 2022 3:26 pm
by zap8600
Octocontrabass wrote: Is there any particular reason why you don't want to use a debugger to check your GDT?
I was wanting to make progress. That usually gives me the motivation to continue working on my OS.

Re: How to make a GDT?

Posted: Mon Oct 31, 2022 3:40 pm
by iansjack
zap8600 wrote:
Octocontrabass wrote: Is there any particular reason why you don't want to use a debugger to check your GDT?
I was wanting to make progress. That usually gives me the motivation to continue working on my OS.
The best way to make progress is to learn how to use a debugger. That stops you wasting a lot of time on uninformed guesses.

Re: How to make a GDT?

Posted: Tue Nov 01, 2022 9:10 am
by zap8600
iansjack wrote: The best way to make progress is to learn how to use a debugger. That stops you wasting a lot of time on uninformed guesses.
That sort of makes sense. I should look at some new problems that I've noticed with my code.

First, when the assembly code reloads the segments, it doesn't point to the 64-bit data segment.

Code: Select all

asm volatile (
		"mov %0, %%rdi\n"
		"lgdt (%%rdi)\n"
		"mov $0x10, %%ax\n"
		"mov %%ax, %%ds\n"
		"mov %%ax, %%es\n"
		"mov %%ax, %%ss\n"
		"mov $0x2b, %%ax\n"
		"ltr %%ax\n"
		: : "r"(&gdt[0].pointer)
);
I believe that it is pointing to the 16-bit segment. It should instead point to 0x30, which I believe is the 64-bit segment.
Second, I think that the TSS data isn't being written to the write entry.

Code: Select all

for (int i = 0; i < 32; ++i) {
		gdt[i].pointer.limit = sizeof(gdt[i].entries)+sizeof(gdt[i].tss_extra)-1;
		gdt[i].pointer.base  = (uintptr_t)&gdt[i].entries;

		uintptr_t addr = (uintptr_t)&gdt[i].tss;
		gdt[i].entries[5].limit_low = sizeof(gdt[i].tss);
		gdt[i].entries[5].base_low = (addr & 0xFFFF);
		gdt[i].entries[5].base_middle = (addr >> 16) & 0xFF;
		gdt[i].entries[5].base_high = (addr >> 24) & 0xFF;
		gdt[i].tss_extra.base_highest = (addr >> 32) & 0xFFFFFFFF;
}
If this is the case though, I believe the problem should be fixed by replacing the 5 with 7.

I may also add this mini debugger to my kernel.

Re: How to make a GDT?

Posted: Tue Nov 01, 2022 11:43 am
by zap8600
I think I have found another problem. I think that my TSS's offset (base) is located in one of the GDT entries.

Code: Select all

void init_gdt()
{
    for (int i = 1; i < 32; ++i) {
		memcpy(&gdt[i], &gdt[0], sizeof(*gdt));
	}

    for (int i = 0; i < 32; ++i) {
		gdt[i].pointer.limit = sizeof(gdt[i].entries)+sizeof(gdt[i].tss_extra)-1;
		gdt[i].pointer.base  = (uintptr_t)&gdt[i].entries;

		uintptr_t addr = (uintptr_t)&gdt[i].tss;
		gdt[i].entries[7].limit_low = sizeof(gdt[i].tss);
		gdt[i].entries[7].base_low = (addr & 0xFFFF);
		gdt[i].entries[7].base_middle = (addr >> 16) & 0xFF;
		gdt[i].entries[7].base_high = (addr >> 24) & 0xFF;
		gdt[i].tss_extra.base_highest = (addr >> 32) & 0xFFFFFFFF;
	}
...
}
Is this wrong with my current segments?