I've been working on my kernel for a bit now, and I really want to enter userspace.
I have a few functions down, and I believe my OS would last... at least a reasonable amount of time in userspace.
So, I know in order for me to return to ring 0 from ring 3, I need a TSS.
I don't plan on doing that quite yet, I just want to get into userspace.
I know I need entries in my GDT for user code/data. I don't know what the entries should look like, or differ from the kernel entries, or what order the GDT needs to be laid out in.
And then finally, what do I do to officiate my entry into userspace?
How to enter userspace
How to enter userspace
Skylight: https://github.com/austanss/skylight
I make stupid mistakes and my vision is terrible. Not a good combination.
NOTE: Never respond to my posts with "it's too hard".
I make stupid mistakes and my vision is terrible. Not a good combination.
NOTE: Never respond to my posts with "it's too hard".
- AndrewAPrice
- Member
- Posts: 2300
- Joined: Mon Jun 05, 2006 11:00 pm
- Location: USA (and Australia)
Re: How to enter userspace
You probably want a way to syscall back into the kernel unless you map 0xb8000 to usermode. Are you in protected mode or long mode?rizxt wrote:So, I know in order for me to return to ring 0 from ring 3, I need a TSS.
I don't plan on doing that quite yet, I just want to get into userspace.
I found the TSS straight foward to work with in long mode. The most difficult part is splitting up the TSS's address + size to write it into the GDT. The only thing you'd need in the actual TSS right now is the stack pointer to use for when you enter an interrupt. But, I don't know if you actually need a TSS if you keep interrupts disabled.
This is for long mode. I have 5 segments in my GDT (kernel + userspace, code + data), and a reference to the TSS.rizxt wrote:I know I need entries in my GDT for user code/data. I don't know what the entries should look like, or differ from the kernel entries, or what order the GDT needs to be laid out in.
Code: Select all
[GLOBAL Gdt64]
Gdt64:
; Invalid segment
DQ 0x0000000000000000 ; 0x0
; Kernel code: RW, executable, code/data segment, present, 64-bit, ring 0
DQ 0x00209A0000000000 ; 0x8
; Kernel data: RW, data, code/data segment, present, ring 0
DQ 0x0000920000000000 ; 0x10
; User data: RW, data, code/data segment, present, ring 3
DQ 0x0020F20000000000 ; 0x18
; User code: RW, executable, code/data segment, present, 64-bit, ring 3
DQ 0x0020FA0000000000 ; 0x20
[GLOBAL TSSEntry]
TSSEntry:
DQ 0x0000000000000000 ; 0x28
DQ 0x0000000000000000
Set your segments, then jump into it. See Getting to Ring 3#Entering_Ring_3rizxt wrote:And then finally, what do I do to officiate my entry into userspace?
My OS is Perception.
Re: How to enter userspace
Long mode. Also, reading that article, I noticed it uses IRET. The difference between x86 and x86_64 IRET is important, I believe. And it appears that article is written for x86.AndrewAPrice wrote:You probably want a way to syscall back into the kernel unless you map 0xb8000 to usermode. Are you in protected mode or long mode?rizxt wrote:So, I know in order for me to return to ring 0 from ring 3, I need a TSS.
I don't plan on doing that quite yet, I just want to get into userspace.
I found the TSS straight foward to work with in long mode. The most difficult part is splitting up the TSS's address + size to write it into the GDT. The only thing you'd need in the actual TSS right now is the stack pointer to use for when you enter an interrupt. But, I don't know if you actually need a TSS if you keep interrupts disabled.
This is for long mode. I have 5 segments in my GDT (kernel + userspace, code + data), and a reference to the TSS.rizxt wrote:I know I need entries in my GDT for user code/data. I don't know what the entries should look like, or differ from the kernel entries, or what order the GDT needs to be laid out in.
Code: Select all
[GLOBAL Gdt64] Gdt64: ; Invalid segment DQ 0x0000000000000000 ; 0x0 ; Kernel code: RW, executable, code/data segment, present, 64-bit, ring 0 DQ 0x00209A0000000000 ; 0x8 ; Kernel data: RW, data, code/data segment, present, ring 0 DQ 0x0000920000000000 ; 0x10 ; User data: RW, data, code/data segment, present, ring 3 DQ 0x0020F20000000000 ; 0x18 ; User code: RW, executable, code/data segment, present, 64-bit, ring 3 DQ 0x0020FA0000000000 ; 0x20 [GLOBAL TSSEntry] TSSEntry: DQ 0x0000000000000000 ; 0x28 DQ 0x0000000000000000
Set your segments, then jump into it. See Getting to Ring 3#Entering_Ring_3rizxt wrote:And then finally, what do I do to officiate my entry into userspace?
Skylight: https://github.com/austanss/skylight
I make stupid mistakes and my vision is terrible. Not a good combination.
NOTE: Never respond to my posts with "it's too hard".
I make stupid mistakes and my vision is terrible. Not a good combination.
NOTE: Never respond to my posts with "it's too hard".
Re: How to enter userspace
It's pretty much the same thing, but you use "iretq" instead of "iret", Also you don't need to set %fs and %gs (and likely don't want to).rizxt wrote:Long mode. Also, reading that article, I noticed it uses IRET. The difference between x86 and x86_64 IRET is important, I believe. And it appears that article is written for x86.
x86_64:
Code: Select all
JumpToUserMode:
# rdi = user args
# rsi = entry point in user space
# rdx = user space stack
movq $0x1b, %rax # Selector 0x18 (User Data) + RPL 3
movw %ax, %ds
movw %ax, %es
# Build a fake iret frame
pushq %rax # Selector 0x18 (User Data) + RPL 3
pushq %rdx # User space stack
pushq $0x202 # rflags = interrupt enable + reserved bit
pushq $0x23 # Selector 0x20 (User Code) + RPL 3
pushq %rsi # Entry point in user space
iretq
Re: How to enter userspace
Right, so with your help I managed to get CPL to 3, and iret to my userspace entrypoint. I now simply need to align my userspace code to it's own page, and then I can easily set it's page to user privileges.
Skylight: https://github.com/austanss/skylight
I make stupid mistakes and my vision is terrible. Not a good combination.
NOTE: Never respond to my posts with "it's too hard".
I make stupid mistakes and my vision is terrible. Not a good combination.
NOTE: Never respond to my posts with "it's too hard".
-
- Member
- Posts: 148
- Joined: Sun Aug 23, 2020 4:35 pm
Re: How to enter userspace
Just curious, is this the kernel, a program, or test code that you are trying to execute in userspace?
Re: How to enter userspace
This is part of the kernel executable. I'm trying to get to userspace so I can implement syscalls + test them, and also implement a UI outside of ring 0.foliagecanine wrote:Just curious, is this the kernel, a program, or test code that you are trying to execute in userspace?
Skylight: https://github.com/austanss/skylight
I make stupid mistakes and my vision is terrible. Not a good combination.
NOTE: Never respond to my posts with "it's too hard".
I make stupid mistakes and my vision is terrible. Not a good combination.
NOTE: Never respond to my posts with "it's too hard".
-
- Member
- Posts: 426
- Joined: Tue Apr 03, 2018 2:44 am
Re: How to enter userspace
Just don't do what I did, which was to return via iret having first pushed 0 for the eflags value. Ended up with no interrupts when running in user mode and didn't even notice until I started running CPU heavy user coderizxt wrote:This is part of the kernel executable. I'm trying to get to userspace so I can implement syscalls + test them, and also implement a UI outside of ring 0.foliagecanine wrote:Just curious, is this the kernel, a program, or test code that you are trying to execute in userspace?