Virtual 8086 Mode.
More...
|
#define | CODE_ADDRESS ((void*) 0x500) |
| Where the assembly code will be located. More...
|
|
#define | IVT_ADDRESS ((void*) 0) |
| The real mode IVT (= Interrupt Vector Table) lies at the start of memory. More...
|
|
#define | OPERAND_SIZE 0x66 |
| opcode for overriding operand size
|
|
#define | OPCODE_PUSHF 0x9C |
| PUSHF triggers a GPF inside VM86 mode.
|
|
#define | OPCODE_POPF 0x9D |
| POPF triggers a GPF inside VM86 mode.
|
|
#define | OPCODE_INT_3 0xCC |
| INT $3 triggers a GPF inside VM86 mode.
|
|
#define | OPCODE_INT 0xCD |
| INT triggers a GPF inside VM86 mode.
|
|
#define | OPCODE_IRET 0xCF |
| IRET triggers a GPF inside VM86 mode.
|
|
#define | OPCODE_CLI 0xFA |
| CLI triggers a GPF inside VM86 mode.
|
|
#define | OPCODE_STI 0xFB |
| STI triggers a GPF inside VM86 mode.
|
|
#define | CASE_IN(opcode, in_func, operand, inc, type) |
| Emulates an IN instruction. More...
|
|
#define | CASE_OUT(opcode, out_func, operand, inc) |
| Emulates an OUT instruction. More...
|
|
|
static vm86_farptr_t | vm86_get_farptr (void *addr) |
| Translate an address into a far pointer. More...
|
|
static void | vm86_write_farptr (uint16_t *segment, uint16_t *offset, vm86_farptr_t farptr) |
| Writes a far pointer into another location. More...
|
|
static void * | vm86_get_address (vm86_farptr_t farptr) |
| Translate a far pointer into an address. More...
|
|
task_pid_t | vm86_create_task (void *code_start, void *code_end, page_directory_t *page_directory, size_t kernel_stack_len, size_t user_stack_len, isr_registers_t *registers) |
| Creates a VM86 task. More...
|
|
void | vm86_call_bios (uint8_t interrupt, isr_registers_t *registers) |
| Calls a BIOS interrupt. More...
|
|
static void | vm86_push (cpu_state_t *cpu, uint16_t value) |
| Emulates a PUSH instruction. More...
|
|
static uint16_t | vm86_pop (cpu_state_t *cpu) |
| Emulates a POP instruction. More...
|
|
static void | vm86_increment_eip (cpu_state_t *cpu, size_t inc) |
| Emulates the completion of an instruction. More...
|
|
static uint8_t | vm86_monitor (cpu_state_t *cpu) |
| Monitors a VM86 task by emulating sensitive instructions. More...
|
|
static cpu_state_t * | vm86_handle_gpf (cpu_state_t *cpu) |
| Handles general protection faults. More...
|
|
void | vm86_init () |
| Initializes VM86 mode.
|
|
Virtual 8086 Mode.
The VM86 mode runs 16-bit code and calls BIOS functions. A VM86 monitor is needed to emulate sensitive instructions.
- See also
- vm86_asm.S
-
http://wiki.osdev.org/Virtual_8086_Mode
-
http://www.lowlevel.eu/wiki/Virtual_8086_Mode
-
http://osdev.berlios.de/v86.html
-
http://www.rcollins.org/articles/pvi1/pvi1.html
-
http://lowlevel.eu/wiki/Speicherbereiche
-
http://www.brokenthorn.com/Resources/OSDevVid2.html
-
http://ref.x86asm.net/coder32.html
#define CASE_IN |
( |
|
opcode, |
|
|
|
in_func, |
|
|
|
operand, |
|
|
|
inc, |
|
|
|
type |
|
) |
| |
Value:case (opcode): \
*(type*) &cpu->r.eax = (in_func)(operand); \
vm86_increment_eip(cpu, (inc)); \
break;
Emulates an IN instruction.
- Parameters
-
opcode | the opcode of the instruction to emulate |
in_func | the function to call |
operand | the input port |
inc | the instruction length in bytes |
type | in_func's return type |
Definition at line 54 of file vm86.c.
#define CASE_OUT |
( |
|
opcode, |
|
|
|
out_func, |
|
|
|
operand, |
|
|
|
inc |
|
) |
| |
Value:case (opcode): \
(out_func)((operand), cpu->r.eax); \
vm86_increment_eip(cpu, (inc)); \
break;
Emulates an OUT instruction.
- Parameters
-
opcode | the opcode of the instruction to emulate |
out_func | the function to call |
operand | the output port |
inc | the instruction length in bytes |
Definition at line 67 of file vm86.c.
#define CODE_ADDRESS ((void*) 0x500) |
Where the assembly code will be located.
The code will be memcpy'd to this location. We set this to the beginning of conventional memory. This way only one VM86 task can be run at a time!
Definition at line 33 of file vm86.c.
#define IVT_ADDRESS ((void*) 0) |
The real mode IVT (= Interrupt Vector Table) lies at the start of memory.
One of the few occasions to dereference a null pointer ^^
Definition at line 36 of file vm86.c.
Calls a BIOS interrupt.
- Parameters
-
interrupt | the interrupt vector to call |
registers | the parameters for the call |
Definition at line 205 of file vm86.c.
Creates a VM86 task.
- See also
- task_create_detailed
- Parameters
-
code_start | start of the 16-bit code |
code_end | end of the 16-bit code |
page_directory | a page directory for the task, if 0 a new one is created |
kernel_stack_len | number of bytes to allocate for the kernel stack |
user_stack_len | number of bytes to allocate for the user stack |
registers | parameters to pass to the 16-bit code |
- Returns
- the task's PID
Identity maps the first MiB so our VM86 task can operate inside it. Because this is not inside the user domain (1GiB and onwards), bypasses domain checking.
Copies the 16-bit code into conventional memory. We could map the code as virtual memory, but copying is easier ;) Note that this code might not reference any labels or so, because it needs to be position independent. For calling the BIOS this is enough, if we started writing real 16-bit programs, we would need to improve this.
The user stack is located after the code (we assume that's free memory).
Definition at line 145 of file vm86.c.
Translate a far pointer into an address.
- Parameters
-
- Returns
- the address
Definition at line 129 of file vm86.c.
Translate an address into a far pointer.
- Parameters
-
- Returns
- the far pointer
There are many ways to translate an address into a far pointer. We do it in such a way that our code is likely to only use one segment (which is easier than handling multiple segments). The equation used is:
1 paddr = segment * 16 + offset
Definition at line 91 of file vm86.c.
Handles general protection faults.
- Parameters
-
- Returns
- a (possibly altered) CPU state
Definition at line 337 of file vm86.c.
static void vm86_increment_eip |
( |
cpu_state_t * |
cpu, |
|
|
size_t |
inc |
|
) |
| |
|
static |
Emulates the completion of an instruction.
- Parameters
-
cpu | the CPU state to modify |
inc | the instruction length in bytes |
Definition at line 249 of file vm86.c.
Monitors a VM86 task by emulating sensitive instructions.
- Parameters
-
- Returns
- whether the monitor handled the GPF
Definition at line 260 of file vm86.c.
Emulates a POP instruction.
- Parameters
-
cpu | the CPU state to modify |
- Returns
- the popped value
Definition at line 235 of file vm86.c.
static void vm86_push |
( |
cpu_state_t * |
cpu, |
|
|
uint16_t |
value |
|
) |
| |
|
static |
Emulates a PUSH instruction.
- Parameters
-
cpu | the CPU state to modify |
value | the value to push |
Definition at line 222 of file vm86.c.
static void vm86_write_farptr |
( |
uint16_t * |
segment, |
|
|
uint16_t * |
offset, |
|
|
vm86_farptr_t |
farptr |
|
) |
| |
|
static |
Writes a far pointer into another location.
- Parameters
-
segment | where to write the segment |
offset | where to write the offset |
farptr | the far pointer to write |
Definition at line 118 of file vm86.c.