I can't install Task Register(

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
User avatar
mrjbom
Member
Member
Posts: 317
Joined: Sun Jul 21, 2019 7:34 am

I can't install Task Register(

Post by mrjbom »

Hi.
I have previously discussed this issue here, but we have not been able to achieve a solution, so I have to write about it again...

So, here is my code that deals with setting up GDT and trying to load TR.

First it creates 6 entries in gdt_entries array
0. NULL
1. Kernel Code
2. Kernel Data
3. Usermode Code
4. Usermode Data
5. TSS
After that, everything is successfully flush GDT.
Then I take the ESP to use it in the write_tss() function that configures the TSS.
Then I configure the IDT to track exceptions that may occur when trying to execute the LTR statement.
And finally I try to load TR using the function tss_flush(), as a parameter I specify the number offset to the TSS entry in GDT(0x5 * 0x8 = 0x28).

While calling the tss_flush() function, while trying to execute the LTR statement, I encounter an exception #GP, with the error code d440.
Here's what it means:
Exception inside the processor
The Selector Index references a descriptor in the GDT.
index = 6792
However, the problem is that there is no such index in my GDT, I do not know what exactly it does not like.
nexos
Member
Member
Posts: 1081
Joined: Tue Feb 18, 2020 3:29 pm
Libera.chat IRC: nexos

Re: I can't install Task Register(

Post by nexos »

Remove this section in write_tss

Code: Select all

uint32_t base = (uint32_t) &tss;
	uint32_t limit = sizeof(tss)-1;

	tss_descriptor_t* tss_d = (tss_descriptor_t*) &gdt_entries[num];

	tss_d->base_15_0 = base & 0xFFFF;
	tss_d->base_23_16 = (base >> 16) & 0xFF;
	tss_d->base_31_24 = (base >> 24) & 0xFF;

	tss_d->limit_15_0 = limit & 0xFFFF;
	tss_d->limit_19_16 = (limit >> 16) & 0xF;

	tss_d->present = 1;
	tss_d->sys = 0;
	tss_d->DPL = 0;
	tss_d->type = 9;

	tss_d->AVL = 0;
	tss_d->allways_zero = 0;
	tss_d->gran = 0;
And call write_tss before calling lgdt. Call ltr after writing the GDT.
Then, it should work
"How did you do this?"
"It's very simple — you read the protocol and write the code." - Bill Joy
Projects: NexNix | libnex | nnpkg
User avatar
mrjbom
Member
Member
Posts: 317
Joined: Sun Jul 21, 2019 7:34 am

Re: I can't install Task Register(

Post by mrjbom »

nexos wrote:And call write_tss before calling lgdt. Call ltr after writing the GDT.
Then, it should work
Like this?

Code: Select all

write_tss(5, 0x10, stack);
gdt_flush((uint32_t)&gdt_ptr);
tss_flush(0x28);
nexos
Member
Member
Posts: 1081
Joined: Tue Feb 18, 2020 3:29 pm
Libera.chat IRC: nexos

Re: I can't install Task Register(

Post by nexos »

Yes, just like that.
"How did you do this?"
"It's very simple — you read the protocol and write the code." - Bill Joy
Projects: NexNix | libnex | nnpkg
User avatar
mrjbom
Member
Member
Posts: 317
Joined: Sun Jul 21, 2019 7:34 am

Re: I can't install Task Register(

Post by mrjbom »

nexos wrote:Yes, just like that.
Just in case, I will give the code of both changed functions.
However, this does not solve the problem, the error code is still the same.

Code: Select all

void init_gdt(void)
{
  gdt_ptr.limit = (sizeof(gdt_entry_t) * 6) - 1;
  gdt_ptr.base = (uint32_t)&gdt_entries;
  
  gdt_set_gate(0, 0, 0, 0, 0);	/* Null segment */
  gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF); /* Code segment */
  gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF); /* Data segment */
  gdt_set_gate(3, 0, 0xFFFFFFFF, 0xFA, 0xCF); /* User mode code segment */
  gdt_set_gate(4, 0, 0xFFFFFFFF, 0xF2, 0xCF); /* User mode data segment */
  gdt_set_gate(5, (uint32_t)&tss, (uint32_t)&tss + sizeof(tss_entry_t), 0xE9, 0xCF);

  uint32_t stack = 0;
  __asm__ volatile ("mov %%esp, %0" : "=r"(stack));
  write_tss(5, 0x10, stack);
  
  gdt_flush((uint32_t)&gdt_ptr);
  tss_flush(0x28);
  
  init_idt();
}

Code: Select all

void write_tss(int32_t num, uint32_t ss0, uint32_t esp0)
{
	memset(&tss, 0, sizeof(tss_entry_t));

	tss.ss0 = ss0;
	tss.esp0 = esp0;

	tss.cs = 0x08;

	tss.ss = tss.ds = tss.es = tss.fs = tss.gs = 0x10;

	tss.iomap = 0xFF;
	tss.iomap_offset = (uint16_t) ( (uint32_t) &tss.iomap - (uint32_t) &tss );
}
nexos
Member
Member
Posts: 1081
Joined: Tue Feb 18, 2020 3:29 pm
Libera.chat IRC: nexos

Re: I can't install Task Register(

Post by nexos »

Here is what I do

Code: Select all

memset(&tss, 0, sizeof(tss_entry));

    tss.ss0 = kernelSS;

    tss.esp0 = kernelESP;

    tss.cs = 0x0b;

    tss.ss = tss.ds = tss.es = tss.fs = tss.gs = 0x13;

    tss.iomap = sizeof(tss_entry);

    tss_flush();
"How did you do this?"
"It's very simple — you read the protocol and write the code." - Bill Joy
Projects: NexNix | libnex | nnpkg
User avatar
mrjbom
Member
Member
Posts: 317
Joined: Sun Jul 21, 2019 7:34 am

Re: I can't install Task Register(

Post by mrjbom »

nexos wrote:Here is what I do

Code: Select all

memset(&tss, 0, sizeof(tss_entry));

    tss.ss0 = kernelSS;

    tss.esp0 = kernelESP;

    tss.cs = 0x0b;

    tss.ss = tss.ds = tss.es = tss.fs = tss.gs = 0x13;

    tss.iomap = sizeof(tss_entry);

    tss_flush();
I tried using the same values during tss setup and for tss_flush

Code: Select all

tss.cs = 0x0B;
tss.ss = tss.ds = tss.es = tss.fs = tss.gs = 0x13;

Code: Select all

tss_flush(0x2B);
In this case the error code points to such an index in GDT - 2142
It is absolutely unclear why this particular index contains an error.
nexos
Member
Member
Posts: 1081
Joined: Tue Feb 18, 2020 3:29 pm
Libera.chat IRC: nexos

Re: I can't install Task Register(

Post by nexos »

Try running it in Bochs. Check the Bochs log and post what it says.
"How did you do this?"
"It's very simple — you read the protocol and write the code." - Bill Joy
Projects: NexNix | libnex | nnpkg
sj95126
Member
Member
Posts: 151
Joined: Tue Aug 11, 2020 12:14 pm

Re: I can't install Task Register(

Post by sj95126 »

mrjbom wrote:And finally I try to load TR using the function tss_flush(), as a parameter I specify the number offset to the TSS entry in GDT(0x5 * 0x8 = 0x28).
As an aside, I strongly recommend getting away from the concept that a selector is in some way a byte offset into the GDT. It's not - it's an index. It's *coincidental* that the index and offset are the same for system-level selectors in the GDT (that is, the lower three bits are 0), but if you ever go to 64-bit mode, you're going to be incredibly confused why nothing works.

I know some tutorials frame things this way and it doesn't help as a learning tool.
kzinti
Member
Member
Posts: 898
Joined: Mon Feb 02, 2015 7:11 pm

Re: I can't install Task Register(

Post by kzinti »

Isn't the index a byte offset? :)
Octocontrabass
Member
Member
Posts: 5572
Joined: Mon Mar 25, 2013 7:01 pm

Re: I can't install Task Register(

Post by Octocontrabass »

mrjbom wrote:In this case the error code points to such an index in GDT - 2142
It is absolutely unclear why this particular index contains an error.
Because you are loading the value in memory at address 0x2B into the task register, instead of the value 0x2B.
User avatar
mrjbom
Member
Member
Posts: 317
Joined: Sun Jul 21, 2019 7:34 am

Re: I can't install Task Register(

Post by mrjbom »

Octocontrabass wrote:
mrjbom wrote:In this case the error code points to such an index in GDT - 2142
It is absolutely unclear why this particular index contains an error.
Because you are loading the value in memory at address 0x2B into the task register, instead of the value 0x2B.
Ahaha, my God, I spent so much time solving this problem, and the error was so simple, now it's clear why error code pointed to incomprehensible entries in GDT.

Thank you all for your help! ♥
Post Reply