📄 l.s
字号:
RETTEXT getcr4(SB), $0 /* CR4 - extensions */ MOVL CR4, AX RETTEXT _cycles(SB), $0 /* time stamp counter */ RDTSC MOVL vlong+0(FP), CX /* &vlong */ MOVL AX, 0(CX) /* lo */ MOVL DX, 4(CX) /* hi */ RETTEXT rdmsr(SB), $0 /* model-specific register */ MOVL index+0(FP), CX RDMSR MOVL vlong+4(FP), CX /* &vlong */ MOVL AX, 0(CX) /* lo */ MOVL DX, 4(CX) /* hi */ RET TEXT wrmsr(SB), $0 MOVL index+0(FP), CX MOVL lo+4(FP), AX MOVL hi+8(FP), DX WRMSR RETTEXT mb386(SB), $0 POPL AX /* return PC */ PUSHFL PUSHL CS PUSHL AX IRETL/* * special traps */TEXT intr0(SB),$0 PUSHL $0 PUSHL $0 JMP intrcommonTEXT intr1(SB),$0 PUSHL $0 PUSHL $1 JMP intrcommonTEXT intr2(SB),$0 PUSHL $0 PUSHL $2 JMP intrcommonTEXT intr3(SB),$0 PUSHL $0 PUSHL $3 JMP intrcommonTEXT intr4(SB),$0 PUSHL $0 PUSHL $4 JMP intrcommonTEXT intr5(SB),$0 PUSHL $0 PUSHL $5 JMP intrcommonTEXT intr6(SB),$0 PUSHL $0 PUSHL $6 JMP intrcommonTEXT intr7(SB),$0 PUSHL $0 PUSHL $7 JMP intrcommonTEXT intr8(SB),$0 PUSHL $8 JMP intrcommonTEXT intr9(SB),$0 PUSHL $0 PUSHL $9 JMP intrcommonTEXT intr10(SB),$0 PUSHL $10 JMP intrcommonTEXT intr11(SB),$0 PUSHL $11 JMP intrcommonTEXT intr12(SB),$0 PUSHL $12 JMP intrcommonTEXT intr13(SB),$0 PUSHL $13 JMP intrcommonTEXT intr14(SB),$0 PUSHL $14 JMP intrcommonTEXT intr15(SB),$0 PUSHL $0 PUSHL $15 JMP intrcommonTEXT intr16(SB),$0 PUSHL $0 PUSHL $16 JMP intrcommonTEXT intr24(SB),$0 PUSHL $0 PUSHL $24 JMP intrcommonTEXT intr25(SB),$0 PUSHL $0 PUSHL $25 JMP intrcommonTEXT intr26(SB),$0 PUSHL $0 PUSHL $26 JMP intrcommonTEXT intr27(SB),$0 PUSHL $0 PUSHL $27 JMP intrcommonTEXT intr28(SB),$0 PUSHL $0 PUSHL $28 JMP intrcommonTEXT intr29(SB),$0 PUSHL $0 PUSHL $29 JMP intrcommonTEXT intr30(SB),$0 PUSHL $0 PUSHL $30 JMP intrcommonTEXT intr31(SB),$0 PUSHL $0 PUSHL $31 JMP intrcommonTEXT intr32(SB),$0 PUSHL $0 PUSHL $32 JMP intrcommonTEXT intr33(SB),$0 PUSHL $0 PUSHL $33 JMP intrcommonTEXT intr34(SB),$0 PUSHL $0 PUSHL $34 JMP intrcommonTEXT intr35(SB),$0 PUSHL $0 PUSHL $35 JMP intrcommonTEXT intr36(SB),$0 PUSHL $0 PUSHL $36 JMP intrcommonTEXT intr37(SB),$0 PUSHL $0 PUSHL $37 JMP intrcommonTEXT intr38(SB),$0 PUSHL $0 PUSHL $38 JMP intrcommonTEXT intr39(SB),$0 PUSHL $0 PUSHL $39 JMP intrcommonTEXT intr64(SB),$0 PUSHL $0 PUSHL $64 JMP intrcommonTEXT intrbad(SB),$0 PUSHL $0 PUSHL $0x1ff JMP intrcommonintrcommon: PUSHL DS PUSHL ES PUSHL FS PUSHL GS PUSHAL MOVL $(KDSEL),AX MOVW AX,DS MOVW AX,ES LEAL 0(SP),AX PUSHL AX CALL trap(SB) POPL AX POPAL POPL GS POPL FS POPL ES POPL DS ADDL $8,SP /* error code and trap type */ IRETL/* * interrupt level is interrupts on or off */TEXT spllo(SB),$0 PUSHFL POPL AX STI RETTEXT splhi(SB),$0 PUSHFL POPL AX CLI RETTEXT splx(SB),$0 MOVL s+0(FP),AX PUSHL AX POPFL RET/* * do nothing whatsoever till interrupt happens */TEXT idle(SB),$0 HLT RET/* * Try to determine the CPU type which requires fiddling with EFLAGS. * If the Id bit can be toggled then the CPUID instruciton can be used * to determine CPU identity and features. First have to check if it's * a 386 (Ac bit can't be set). If it's not a 386 and the Id bit can't be * toggled then it's an older 486 of some kind. * * cpuid(id[], &ax, &dx); */#define CPUID BYTE $0x0F; BYTE $0xA2 /* CPUID, argument in AX */TEXT cpuid(SB), $0 MOVL $0x240000, AX PUSHL AX POPFL /* set Id|Ac */ PUSHFL POPL BX /* retrieve value */ MOVL $0, AX PUSHL AX POPFL /* clear Id|Ac, EFLAGS initialised */ PUSHFL POPL AX /* retrieve value */ XORL BX, AX TESTL $0x040000, AX /* Ac */ JZ _cpu386 /* can't set this bit on 386 */ TESTL $0x200000, AX /* Id */ JZ _cpu486 /* can't toggle this bit on some 486 */ MOVL $0, AX CPUID MOVL id+0(FP), BP MOVL BX, 0(BP) /* "Genu" "Auth" "Cyri" */ MOVL DX, 4(BP) /* "ineI" "enti" "xIns" */ MOVL CX, 8(BP) /* "ntel" "cAMD" "tead" */ MOVL $1, AX CPUID JMP _cpuid_cpu486: MOVL $0x400, AX MOVL $0, DX JMP _cpuid_cpu386: MOVL $0x300, AX MOVL $0, DX_cpuid: MOVL ax+4(FP), BP MOVL AX, 0(BP) MOVL dx+8(FP), BP MOVL DX, 0(BP) RET/* * basic timing loop to determine CPU frequency */TEXT aamloop(SB),$0 MOVL c+0(FP),CXaaml1: AAM LOOP aaml1 RETTEXT hello(SB), $0 BYTE $'P'; BYTE $'l'; BYTE $'a'; BYTE $'n'; BYTE $' '; BYTE $'9'; BYTE $' '; BYTE $'f'; BYTE $'r'; BYTE $'o'; BYTE $'m'; BYTE $' '; BYTE $'B'; BYTE $'e'; BYTE $'l'; BYTE $'l'; BYTE $' '; BYTE $'L'; BYTE $'a'; BYTE $'b'; BYTE $'s'; BYTE $'\r'; BYTE $'\n'; BYTE $'\z';TEXT rock(SB), $0 BYTE $0; BYTE $0; BYTE $0; BYTE $0;GLOBL pxe(SB), $4#ifdef PXEDATA pxe+0(SB)/4, $1#elseDATA pxe+0(SB)/4, $0#endif /* PXE *//* * Save registers. */TEXT saveregs(SB), $0 /* appease 8l */ SUBL $32, SP POPL AX POPL AX POPL AX POPL AX POPL AX POPL AX POPL AX POPL AX PUSHL AX PUSHL BX PUSHL CX PUSHL DX PUSHL BP PUSHL DI PUSHL SI PUSHFL XCHGL 32(SP), AX /* swap return PC and saved flags */ XCHGL 0(SP), AX XCHGL 32(SP), AX RETTEXT restoreregs(SB), $0 /* appease 8l */ PUSHL AX PUSHL AX PUSHL AX PUSHL AX PUSHL AX PUSHL AX PUSHL AX PUSHL AX ADDL $32, SP XCHGL 32(SP), AX /* swap return PC and saved flags */ XCHGL 0(SP), AX XCHGL 32(SP), AX POPFL POPL SI POPL DI POPL BP POPL DX POPL CX POPL BX POPL AX RET/* * Assumed to be in protected mode at time of call. * Switch to real mode, execute an interrupt, and * then switch back to protected mode. * * Assumes: * * - no device interrupts are going to come in * - 0-16MB is identity mapped in page tables * - can use code segment 0x1000 in real mode * to get at l.s code */TEXT realmodeidtptr(SB), $0 WORD $(4*256-1) LONG $0TEXT realmode0(SB), $0 CALL saveregs(SB) /* switch to low code address */ LEAL physcode-KZERO(SB), AX JMP *AXTEXT physcode(SB), $0 /* switch to low stack */ MOVL SP, AX MOVL $0x7C00, SP PUSHL AX /* load IDT with real-mode version; GDT already fine */ MOVL realmodeidtptr(SB), IDTR /* edit INT $0x00 instruction below */ MOVL realmodeintr(SB), AX MOVB AX, realmodeintrinst+1(SB) /* disable paging */ MOVL CR0, AX ANDL $0x7FFFFFFF, AX MOVL AX, CR0 /* JMP .+2 to clear prefetch queue*/ BYTE $0xEB; BYTE $0x00 /* jump to 16-bit code segment *//* JMPFAR SELECTOR(3, SELGDT, 0):$again16bit(SB) /**/ BYTE $0xEA LONG $again16bit-KZERO(SB) WORD $SELECTOR(3, SELGDT, 0)TEXT again16bit(SB), $0 /* * Now in 16-bit compatibility mode. * These are 32-bit instructions being interpreted * as 16-bit instructions. I'm being lazy and * not using the macros because I know when * the 16- and 32-bit instructions look the same * or close enough. */ /* disable protected mode and jump to real mode cs */ OPSIZE; MOVL CR0, AX OPSIZE; XORL BX, BX OPSIZE; INCL BX OPSIZE; XORL BX, AX OPSIZE; MOVL AX, CR0 /* JMPFAR 0x1000:now16real */ BYTE $0xEA WORD $now16real-KZERO(SB) WORD $0x1000TEXT now16real(SB), $0 /* copy the registers for the bios call */ LWI(0x1000, rAX) MOVW AX,SS LWI(realmoderegs(SB), rBP) /* offsets are in Ureg */ LXW(44, xBP, rAX) MOVW AX, DS LXW(40, xBP, rAX) MOVW AX, ES OPSIZE; LXW(0, xBP, rDI) OPSIZE; LXW(4, xBP, rSI) OPSIZE; LXW(16, xBP, rBX) OPSIZE; LXW(20, xBP, rDX) OPSIZE; LXW(24, xBP, rCX) OPSIZE; LXW(28, xBP, rAX) CLCTEXT realmodeintrinst(SB), $0 INT $0x00 /* save the registers after the call */ LWI(0x7bfc, rSP) OPSIZE; PUSHFL OPSIZE; PUSHL AX LWI(0x1000, rAX) MOVW AX,SS LWI(realmoderegs(SB), rBP) OPSIZE; SXW(rDI, 0, xBP) OPSIZE; SXW(rSI, 4, xBP) OPSIZE; SXW(rBX, 16, xBP) OPSIZE; SXW(rDX, 20, xBP) OPSIZE; SXW(rCX, 24, xBP) OPSIZE; POPL AX OPSIZE; SXW(rAX, 28, xBP) MOVW DS, AX OPSIZE; SXW(rAX, 44, xBP) MOVW ES, AX OPSIZE; SXW(rAX, 40, xBP) OPSIZE; POPL AX OPSIZE; SXW(rAX, 64, xBP) /* flags */ /* re-enter protected mode and jump to 32-bit code */ OPSIZE; MOVL $1, AX OPSIZE; MOVL AX, CR0 /* JMPFAR SELECTOR(2, SELGDT, 0):$again32bit(SB) /**/ OPSIZE BYTE $0xEA LONG $again32bit-KZERO(SB) WORD $SELECTOR(2, SELGDT, 0)TEXT again32bit(SB), $0 MOVW $SELECTOR(1, SELGDT, 0),AX MOVW AX,DS MOVW AX,SS MOVW AX,ES MOVW AX,FS MOVW AX,GS /* enable paging and jump to kzero-address code */ MOVL CR0, AX ORL $0x80000000, AX MOVL AX, CR0 LEAL again32kzero(SB), AX JMP* AXTEXT again32kzero(SB), $0 /* breathe a sigh of relief - back in 32-bit protected mode */ /* switch to old stack */ PUSHL AX /* match popl below for 8l */ MOVL $0x7BFC, SP POPL SP /* restore idt */ MOVL idtptr(SB),IDTR CALL restoreregs(SB) RETTEXT realmoderegs(SB), $0 LONG $0; LONG $0; LONG $0; LONG $0 LONG $0; LONG $0; LONG $0; LONG $0 LONG $0; LONG $0; LONG $0; LONG $0 LONG $0; LONG $0; LONG $0; LONG $0 LONG $0; LONG $0; LONG $0; LONG $0TEXT realmodeintr(SB), $0 LONG $0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -