// // cpmasm.S // // Performs real-mode switch and then jump to code copied to flash at 0x800:0. // (VxWorks startup code expects a 0 offset, so 0:0x8000 is verboten.) // Mode switch is two part: loading all seg registers with 16-bit segments, then // jumping to realmode segment. GDT in intel_start32.S contains a 16-bit data segment // 0x30 & a 16-bit code segment 0x28. 0x28:0 = 0xf0000 physical. The jump to // 0x28:offset_patch_address requires a far jump with a 16-bit offset, which the assembler // doesn't do. The offset there fore is patched before we get executed by some C code. .text // .code32 .global flashOSBootasm flashOSBootasm: //Load all data segment regs with a 16-bit segment mov $0x30,%ax mov %ax,%ds mov %ax,%es mov %ax,%fs mov %ax,%gs mov %ax,%ss //Jump to a 16-bit code segment ljmp $0x28,$0x00000000 .global offset_patch_address .long offset_patch_address offset_patch_address: movl %cr0, %eax //mov eax,cr0 and $0xfffffffe,%eax //and eax,0ffffffFEh movl %eax,%cr0 //Switch back to real-mode without resetting .global PROTECTION_DISABLED PROTECTION_DISABLED: .code16 //Load all data segments regs with 0 until realmode code sets them mov $0,%ax nop nop mov %ax,%ds mov %ax,%es mov %ax,%fs mov %ax,%ss mov %ax,%gs //opcode for real-mode jump to 800:0 .byte 0xea,0,0,0,0x8 .code32