MichaelPetch wrote:If you are using standard AT&T syntax with GNU assembler then source operand is listed first and destination operand is second. You appear to have them reversed. I will assume that 0x2b was meant to be $0x2B as you want to load ax with 0x2B not what is at memory address DS:0x2B. I would expect you meant:
Yup, realized that about 20 minutes after my second post. I then decided it was time to take a break
I now can now set up the VGA buffer, parse the multiboot header, set up virtual memory with the first 4 MiB identity-mapped (setting all pages as writable and ring 3 accessible, for now), create an IDT (which appears to work, seeing as I can get the divide-by-zero, breakpoint, and page fault ones to fire at will), and set up a GDT like so:
- - zero descriptor
- ring 0 code, base=0, limit=FFFFF, access flags set to 0xC (32-bit and 4KB pages)
- ring 0 data, base=0 limit=FFFFF, access flags set to 0xC
- ring 3 code, base=0, limit=FFFFF, access flags set to 0xC
- ring 3 data, base=0, limit=FFFFF, access flags set to 0xC
- TSS
At this point, I'd love to just be able to switch into ring 3, even if I can't do anything with it yet. I know I can get interrupts to work, so that shouldn't be too painful a process.
I jacked this code from here
http://www.jamesmolloy.co.uk/tutorial_h ... 0Mode.html
Code: Select all
void switch_to_user_mode()
{
// Set up a stack structure for switching to user mode.
asm volatile("
cli; \
mov $0x23, %ax; \
mov %ax, %ds; \
mov %ax, %es; \
mov %ax, %fs; \
mov %ax, %gs; \
\
mov %esp, %eax; \
pushl $0x23; \
pushl %eax; \
pushf; \
pushl $0x1B; \
push $1f; \
iret; \
1:");
}
As I understand it, this puts offset 0x20 (ring 3 data segment) into the data selector register (ds), as well as the other selectors that hypothetically don't get used. Then, it pushes the same selector, the stack pointer, EFLAGS, the ring 3 code selector, and a label to return to (which is just the bottom of the function, which iret then sees as a direction to change to the ring 3 GDT selectors. When I call this function (after doing everything described previously), I get an infinite loop of restarts.
If I throw in an int $0x3 right before that iret, I get my normal breakpoint exception. If I put int $0x3 immediately after iret, I get the triple fault again. Any suggestions?