OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Apr 18, 2024 8:51 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 28 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: Usermode GPF
PostPosted: Sat Nov 26, 2016 6:55 am 
Offline
Member
Member
User avatar

Joined: Fri Aug 07, 2015 6:13 am
Posts: 1134
Hey everyone. I started entering ring 3 like 10 days ago and I am still not inside it.
Attachment:
BSOD-GPF.png
BSOD-GPF.png [ 7.25 KiB | Viewed 4192 times ]

I don't have a clue what is going on?

Assembly Related Code:
Code:
   Enter_User_Mode:
   cli
   mov ax, 0x23
   mov ds, ax
   mov es, ax
   mov fs, ax
   mov gs, ax
   mov eax, esp
   push 0x23
   push eax
   pushf
   pop eax
   or eax, 0x200
   push eax
   push 0x1B
   iret
   ret


TSS Related Code:
Code:
void TSS_Write(int32_t number, uint16_t ss0, uint32_t esp0)
{
   uint32_t base = (uint32_t) & TSS_Entry;
   uint32_t limit = base + sizeof(TSS_Entry);
   GDT_Set_Gate(number, base, limit, 0xE9, 0x00);
   Memory_Set(& TSS_Entry, 0x0, sizeof(TSS_Entry));
   TSS_Entry.ss0 = ss0;
   TSS_Entry.esp0 = esp0;
   TSS_Entry.cs = 0x0B;
   TSS_Entry.ss = 0x13;
   TSS_Entry.ds = 0x13;
   TSS_Entry.es = 0x13;
   TSS_Entry.fs = 0x13;
   TSS_Entry.gs = 0x13;
   TSS_Entry.iomap_base = sizeof(TSS_Entry);
}
Inside GDT_Install:
...
GDT_Set_Gate(3, 0, 0xFFFFFFFF, 0xFA, 0xCF);
GDT_Set_Gate(4, 0, 0xFFFFFFFF, 0xF2, 0xCF);
TSS_Write(5, 0x10, 0x0);
...
TSS_Flush();
...


I just can't figure it out. :|

_________________
OS: Basic OS
About: 32 Bit Monolithic Kernel Written in C++ and Assembly, Custom FAT 32 Bootloader


Top
 Profile  
 
 Post subject: Re: Usermode GPF
PostPosted: Sat Nov 26, 2016 7:00 am 
Offline
Member
Member
User avatar

Joined: Sat Dec 27, 2014 9:11 am
Posts: 901
Location: Maadi, Cairo, Egypt
If I were you, I'd try to enter usermode without the interrupt flag set, and the usermode code would be just a jmp $ or while(1) for testing.
The error code of the fault says the cause is descriptor 0x42 of the LDT, and I assume you don't have an LDT.
Have you tried running in Bochs? What does the log say? What does your usermode code do? Use Bochs' debugger to dump the GDT and take a look if your usermode descriptors contain what they should.

_________________
You know your OS is advanced when you stop using the Intel programming guide as a reference.


Top
 Profile  
 
 Post subject: Re: Usermode GPF
PostPosted: Sat Nov 26, 2016 7:09 am 
Offline
Member
Member
User avatar

Joined: Fri Aug 07, 2015 6:13 am
Posts: 1134
omarrx024 wrote:
If I were you, I'd try to enter usermode without the interrupt flag set, and the usermode code would be just a jmp $ or while(1) for testing.
The error code of the fault says the cause is descriptor 0x42 of the LDT, and I assume you don't have an LDT.
Have you tried running in Bochs? What does the log say? What does your usermode code do? Use Bochs' debugger to dump the GDT and take a look if your usermode descriptors contain what they should.


Okay I will remove the flag. My usermode code does not do anything it is just a while(1) loop that halts the CPU. I do not have an LDT. I have a problem with Bochs it uses my entire CPU power and makes my system unstable. It takes around 5-10 seconds for anything to draw, loading BIOS screen (Bochs default) takes around one minute to load.

Update: without that flag being set:


Attachments:
NoFlagErrorGPF.png
NoFlagErrorGPF.png [ 7.19 KiB | Viewed 4181 times ]

_________________
OS: Basic OS
About: 32 Bit Monolithic Kernel Written in C++ and Assembly, Custom FAT 32 Bootloader


Last edited by Octacone on Sat Nov 26, 2016 7:11 am, edited 2 times in total.
Top
 Profile  
 
 Post subject: Re: Usermode GPF
PostPosted: Sat Nov 26, 2016 7:10 am 
Offline
Member
Member
User avatar

Joined: Sat Dec 27, 2014 9:11 am
Posts: 901
Location: Maadi, Cairo, Egypt
Bochs is easy to set up. Try using the default options; there shouldn't be anything CPU intensive to the degree you describe. It's the easiest way to debug such low-level code.

_________________
You know your OS is advanced when you stop using the Intel programming guide as a reference.


Top
 Profile  
 
 Post subject: Re: Usermode GPF
PostPosted: Sat Nov 26, 2016 7:27 am 
Offline
Member
Member

Joined: Sat Nov 21, 2009 5:11 pm
Posts: 852
In Enter_User_Mode, you forget to push the actual address to jump to. There is also another problem: The user mode code is using the kernel mode stack.


Top
 Profile  
 
 Post subject: Re: Usermode GPF
PostPosted: Sat Nov 26, 2016 7:27 am 
Offline
Member
Member
User avatar

Joined: Fri Aug 07, 2015 6:13 am
Posts: 1134
omarrx024 wrote:
Bochs is easy to set up. Try using the default options; there shouldn't be anything CPU intensive to the degree you describe. It's the easiest way to debug such low-level code.


I am using default options. It is just like line by line, really really really slow. Can't debug with something that runs at 0.05 FPS.

_________________
OS: Basic OS
About: 32 Bit Monolithic Kernel Written in C++ and Assembly, Custom FAT 32 Bootloader


Top
 Profile  
 
 Post subject: Re: Usermode GPF
PostPosted: Sat Nov 26, 2016 7:33 am 
Offline
Member
Member
User avatar

Joined: Fri Aug 07, 2015 6:13 am
Posts: 1134
Gigasoft wrote:
In Enter_User_Mode, you forget to push the actual address to jump to. There is also another problem: The user mode code is using the kernel mode stack.


Now I am getting a triple fault.
Code:
Enter_User_Mode:
   cli
   mov ax, 0x23
   mov ds, ax
   mov es, ax
   mov fs, ax
   mov gs, ax
   mov eax, esp
   push 0x23
   push eax
   pushf
   pop eax
   ;or eax, 0x200
   push eax
   push 0x1B
   push LoopOn
   iret
LoopOn:
   hlt
   jmp LoopOn


Bochs reports: (unk. ctxt): hlt ; f4

Update:
after removing "LoopOn" code I am getting this: (unk. ctxt): mov ax, 0x002b

_________________
OS: Basic OS
About: 32 Bit Monolithic Kernel Written in C++ and Assembly, Custom FAT 32 Bootloader


Top
 Profile  
 
 Post subject: Re: Usermode GPF
PostPosted: Sat Nov 26, 2016 8:44 am 
Offline
Member
Member
User avatar

Joined: Wed Aug 31, 2016 9:53 pm
Posts: 81
Location: San Diego, CA
Try using a separate stack for the ring 3 code. Make sure that the ring 3 stack and code pages are marked as user accessible.

_________________
Some of my open-source projects:
Ext2/ELF32 bootloader
Lightweight x86 assembler, designed to be portable for osdev
Scheme in under 1000 lines of C


Top
 Profile  
 
 Post subject: Re: Usermode GPF
PostPosted: Sat Nov 26, 2016 9:27 am 
Offline
Member
Member

Joined: Sun Feb 01, 2009 6:11 am
Posts: 1070
Location: Germany
Enough people have already mentioned that trying to get into userspace without doing a context switch (i.e. staying on the kernel stack and continue using the kernel state of the registers) is unlikely to result in anything useful, but it shouldn't be in the way of getting into usermode and crashing or hanging there.

The problem with hlt is probably that it's a privileged instruction. So you were in usermode, but the transition back to kernel mode to handle the GPF didn't work.

_________________
Developer of tyndur - community OS of Lowlevel (German)


Top
 Profile  
 
 Post subject: Re: Usermode GPF
PostPosted: Sat Nov 26, 2016 9:49 am 
Offline
Member
Member
User avatar

Joined: Fri Aug 07, 2015 6:13 am
Posts: 1134
crunch wrote:
Try using a separate stack for the ring 3 code. Make sure that the ring 3 stack and code pages are marked as user accessible.


How am I supposed to use a separate stack? I am not running any code at all (except while(1)).

_________________
OS: Basic OS
About: 32 Bit Monolithic Kernel Written in C++ and Assembly, Custom FAT 32 Bootloader


Top
 Profile  
 
 Post subject: Re: Usermode GPF
PostPosted: Sat Nov 26, 2016 10:03 am 
Offline
Member
Member
User avatar

Joined: Fri Aug 07, 2015 6:13 am
Posts: 1134
(unk. ctxt): ltr ax

TSS seems to be a problem?

_________________
OS: Basic OS
About: 32 Bit Monolithic Kernel Written in C++ and Assembly, Custom FAT 32 Bootloader


Top
 Profile  
 
 Post subject: Re: Usermode Triple Fault
PostPosted: Sat Nov 26, 2016 11:16 am 
Offline
Member
Member
User avatar

Joined: Fri Aug 07, 2015 6:13 am
Posts: 1134
I have no idea what is going on. I checked everything twice. I just don't get it. Other people have entered user mode without any problem, every tutorial I've ever seen just magically works.

_________________
OS: Basic OS
About: 32 Bit Monolithic Kernel Written in C++ and Assembly, Custom FAT 32 Bootloader


Top
 Profile  
 
 Post subject: Re: Usermode Triple Fault
PostPosted: Sat Nov 26, 2016 12:38 pm 
Offline
Member
Member
User avatar

Joined: Wed Aug 31, 2016 9:53 pm
Posts: 81
Location: San Diego, CA
octacone wrote:
I have no idea what is going on. I checked everything twice. I just don't get it. Other people have entered user mode without any problem, every tutorial I've ever seen just magically works.


I understand the feeling. Took me about 5 days of banging my head on the wall to get it working. And it was because I wasn't using a separate user-access paged stack.

Code:
enter_usermode:
   ;push ebp
   mov ebp, esp
   cli

   mov ax, 0x20 | 3
   mov ds, ax
   mov es, ax
   mov fs, ax
   mov gs, ax

   push 0x20 | 3   ; push ss3

   mov ecx, [ebp+8]
   push ecx ; push esp3

   pushf  ; push flags onto stack
   pop eax ; pop into eax
   or eax, 0x200 ; set IF (enable interrupts)
   push eax ; push eflags
   push 0x18 | 3 ; push CS, requested priv. level = 3

   xor eax, eax  ; Clear eax
   mov eax, [ebp+4] ; Load new IP into eax
   push eax ; Push EIP onto stack

   iret



To use this, allocate a new physical page for the user-level stack. Map that physical page to some address and make sure that you set the user-accessible flag in the page table entry. enter_usermode(address_of_function, user_stack). Remember that the stack grows down, so if for instance, you chose to map 0x0-0x1000 for your user stack, pass the function 0xF00 as a test.

_________________
Some of my open-source projects:
Ext2/ELF32 bootloader
Lightweight x86 assembler, designed to be portable for osdev
Scheme in under 1000 lines of C


Top
 Profile  
 
 Post subject: Re: Usermode GPF
PostPosted: Mon Nov 28, 2016 12:47 am 
Offline
Member
Member

Joined: Sat Nov 07, 2015 3:12 pm
Posts: 145
if you read what's inside your instruction pointer you will see that it is set jusy after some instruction it was normal to do.. But in user land, it is not!

HLT is a ring0 only instruction.
You should for now do nothing, then later call a yield syscall of sorts.

The reason HLT is privileged is because you can lock a CPU if interrupts are disabled ( which can happen sometimes right after context switch, because sti takes some times before action )


Top
 Profile  
 
 Post subject: Re: Usermode GPF
PostPosted: Mon Nov 28, 2016 9:40 am 
Offline
Member
Member
User avatar

Joined: Fri Aug 07, 2015 6:13 am
Posts: 1134
Boris wrote:
if you read what's inside your instruction pointer you will see that it is set jusy after some instruction it was normal to do.. But in user land, it is not!

HLT is a ring0 only instruction.
You should for now do nothing, then later call a yield syscall of sorts.

The reason HLT is privileged is because you can lock a CPU if interrupts are disabled ( which can happen sometimes right after context switch, because sti takes some times before action )


I figured as much. Forgot that "hlt" was privileged instruction. #-o

_________________
OS: Basic OS
About: 32 Bit Monolithic Kernel Written in C++ and Assembly, Custom FAT 32 Bootloader


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 28 posts ]  Go to page 1, 2  Next

All times are UTC - 6 hours


Who is online

Users browsing this forum: Bing [Bot] and 105 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group