Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ring 3 Execution & GDT Refactoring #177

Open
Kfeavel opened this issue Dec 22, 2020 · 3 comments
Open

Ring 3 Execution & GDT Refactoring #177

Kfeavel opened this issue Dec 22, 2020 · 3 comments

Comments

@Kfeavel
Copy link
Member

Kfeavel commented Dec 22, 2020

Wiki Page - Ring 3
Wiki Page - GDT

Alright, so our GDT code is a disaster. We need to work the GDT struct to use bitfields so that we don't have to have magic values like 0x00F0FF00 floating around in gdt.cpp.

The wiki page "Getting to Ring 3" shows the following as an example of a bitfield GDT struct that we could base our design off of.

struct gdt_entry_bits
{
	unsigned int limit_low:16;
	unsigned int base_low : 24;
     //attribute byte split into bitfields
	unsigned int accessed :1;
	unsigned int read_write :1; //readable for code, writable for data
	unsigned int conforming_expand_down :1; //conforming for code, expand down for data
	unsigned int code :1; //1 for code, 0 for data
	unsigned int always_1 :1; //should be 1 for everything but TSS and LDT
	unsigned int DPL :2; //priviledge level
	unsigned int present :1;
     //and now into granularity
	unsigned int limit_high :4;
	unsigned int available :1;
	unsigned int always_0 :1; //should always be 0
	unsigned int big :1; //32bit opcodes for code, uint32_t stack for data
	unsigned int gran :1; //1 to use 4k page addressing, 0 for byte addressing
	unsigned int base_high :8;
} __packed; //or __attribute__((packed))
@Kfeavel Kfeavel assigned Kfeavel and unassigned Kfeavel Dec 22, 2020
@Kfeavel
Copy link
Member Author

Kfeavel commented Dec 22, 2020

Wait... we may already have GDT segments for user mode...

gdt.cpp

    px_gdt_set_gate(0, 0, 0, 0);                     // Null segment
    px_gdt_set_gate(1, 0, 0x000FFFFF, GDT_CODE_PL0); // Kernel code segment
    px_gdt_set_gate(2, 0, 0x000FFFFF, GDT_DATA_PL0); // Kernel data segment
    px_gdt_set_gate(3, 0, 0x000FFFFF, GDT_CODE_PL3); // User mode code segment
    px_gdt_set_gate(4, 0, 0x000FFFFF, GDT_DATA_PL3); // User mode data segment

So... maybe we just need to implement the jump? Regardless, we should restructure the GDT code to use bitfields instead of magic values.

@Kfeavel
Copy link
Member Author

Kfeavel commented Dec 22, 2020

We also need to decide now how we want to perform syscalls. If we want to use Intel's sysenter and sysexit instructions then we have to structure our GDT a certain way.

If you are using the Intel SYSENTER/SYSEXIT routines, the GDT must be structured like this:

Any descriptors preceding (null descriptor, special kernel stuff, etc.)
A DPL 0 code segment descriptor (the one that SYSENTER will use)
A DPL 0 data segment descriptor (for the SYSENTER stack)
A DPL 3 code segment (for the code after SYSEXIT)
A DPL 3 data segment (for the user-mode stack after SYSEXIT)
Any other descriptors

@Kfeavel
Copy link
Member Author

Kfeavel commented Dec 22, 2020

Also, unless I'm missing something, I think Panix just straight up doesn't setup the TSS at all, which is problematic to say the least.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant