Closed DCNick3 closed 4 years ago
Hello,
There's number of ways that the FPU can be initialized. Every operating system will do it differently -- for instance, OS/2 handles floating point exceptions using IRQ13. I added a routine that will do just that, but that's just the way that mine (Linux x86-64) does it. If it doesn't suit your needs (to simulate OS/2, for instance), you'll have to tinker with some of the bits yourself.
Alternatively, you can map a page to memory, write a bit of shellcode, and then execute it:
static uint8_t mem[4096];
static uint8_t data[] = { 0x0F, 0x20, 0xC0, 0x83, 0xE0, 0xF3, 0x83, 0xC8, 0x20, 0x0F, 0x22, 0xC0, 0xDB, 0xE3 };
/*
Disassembly, for those interested:
0: 0f 20 c0 mov eax,cr0
3: 83 e0 f3 and eax,0xfffffff3 // ~(TS | EM)
6: 83 c8 20 or eax,0x20
9: 0f 22 c0 mov cr0,eax
c: db e3 fninit
*/
static void* mem_stuff(uint32_t addr, int write)
{
UNUSED(write);
return mem + addr;
}
void setup_cpu(void)
{
cpu_init();
cpu_init_32bit();
memcpy(mem, data, 14);
cpu_set_state(CPU_PHYSEIP, 0);
cpu_register_mem_refill_handler(mem_stuff);
cpu_run(5);
}
Even though real operating systems will initialize FPU during their boot process (by issuing
finit
instruction), it would be more convenient for libcpu user if the FPU was already initialized.