github.com/andrewsun2898/u-root@v6.0.1-0.20200616011413-4b2895c1b815+incompatible/pkg/boot/multiboot/internal/trampoline/trampoline_linux_amd64.s (about) 1 // Copyright 2018 the u-root Authors. All rights reserved 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // We want all the trampoline's assembly code to be located 6 // in a contiguous byte range in a compiled binary. 7 // Go compiler does not guarantee that. Still, current version 8 // of compiler puts all pieces together. 9 10 #include "textflag.h" 11 12 #define MSR_EFER 0xC0000080 13 #define EFER_LME 0xFFFFFEFF 14 #define CR0_PG 0x0FFFFFFF 15 16 #define DATA_SEGMENT 0x00CF92000000FFFF 17 #define CODE_SEGMENT 0x00CF9A000000FFFF 18 19 TEXT ·start(SB),NOSPLIT,$0 20 // Create GDT pointer on stack. 21 LEAQ gdt(SB), CX 22 SHLQ $16, CX 23 ORQ $(4*8 - 1), CX 24 PUSHQ CX 25 26 LGDT (SP) 27 28 // Store value of multiboot info addr in BX. 29 // Don't modify BX. 30 MOVL info(SB), BX 31 32 // Store value of mu(l)tiboot magic in SI. 33 // Don't modify SI. 34 MOVL magic(SB), SI 35 36 // Far return doesn't work on QEMU in 64-bit mode, 37 // let's do far jump. 38 // 39 // In a regular plan9 assembly we can do something like: 40 // BYTE $0xFF; BYTE $0x2D 41 // LONG $bootaddr(SB) 42 // TEXT bootaddr(SB),NOSPLIT,$0 43 // LONG $boot(SB) 44 // LONG $0x8 45 // 46 // Go compiler doesn't let us do it. 47 // 48 // Setup offset to make a far jump from boot(SB) 49 // to a final kernel in a 32-bit mode. 50 MOVL entry(SB), AX 51 MOVL AX, farjump32+1(SB) 52 53 // Setup offset to make a far jump to boot(SB) 54 // to switch from 64-bit mode to 32-bit mode. 55 LEAQ boot(SB), CX 56 MOVL CX, farjump64+6(SB) 57 JMP farjump64(SB) 58 59 60 TEXT boot(SB),NOSPLIT,$0 61 // We are in 32-bit mode now. 62 // 63 // Be careful editing this code!!! Go compiler 64 // interprets all commands as 64-bit commands. 65 66 // Disable paging. 67 MOVL CR0, AX 68 ANDL $CR0_PG, AX 69 MOVL AX, CR0 70 71 // Disable long mode. 72 MOVL $MSR_EFER, CX 73 RDMSR 74 ANDL $EFER_LME, AX 75 WRMSR 76 77 // Disable PAE. 78 XORL AX, AX 79 MOVL AX, CR4 80 81 // Load data segments. 82 MOVL $0x10, AX // GDT 0x10 data segment 83 BYTE $0x8e; BYTE $0xd8 // MOVL AX, DS 84 BYTE $0x8e; BYTE $0xc0 // MOVL AX, ES 85 BYTE $0x8e; BYTE $0xd0 // MOVL AX, SS 86 BYTE $0x8e; BYTE $0xe0 // MOVL AX, FS 87 BYTE $0x8e; BYTE $0xe8 // MOVL AX, GS 88 89 // We stored the magic in SI before the far jump. 90 MOVL SI, AX 91 JMP farjump32(SB) 92 93 // Unreachable code. 94 // Need reference text labels for compiler to 95 // include them to a binary. 96 JMP infotext(SB) 97 JMP entrytext(SB) 98 JMP magictext(SB) 99 100 TEXT farjump64(SB),NOSPLIT,$0 101 BYTE $0xFF; BYTE $0x2D; LONG $0x0 // ljmp *(ip) 102 103 LONG $0x0 // farjump64+6(SB) 104 LONG $0x8 // code segment 105 106 TEXT farjump32(SB),NOSPLIT,$0 107 // ljmp $0x18, offset 108 BYTE $0xEA 109 LONG $0x0 // farjump32+1(SB) 110 WORD $0x18 // code segment 111 112 TEXT gdt(SB),NOSPLIT,$0 113 QUAD $0x0 // 0x0 null entry 114 QUAD $CODE_SEGMENT // 0x8 115 QUAD $DATA_SEGMENT // 0x10 116 QUAD $CODE_SEGMENT // 0x18 117 118 TEXT infotext(SB),NOSPLIT,$0 119 // u-root-info-long 120 BYTE $'u'; BYTE $'-'; BYTE $'r'; BYTE $'o'; BYTE $'o'; 121 BYTE $'t'; BYTE $'-'; BYTE $'i'; BYTE $'n'; BYTE $'f'; 122 BYTE $'o'; BYTE $'-'; BYTE $'l'; BYTE $'o'; BYTE $'n'; 123 BYTE $'g'; 124 TEXT info(SB),NOSPLIT,$0 125 LONG $0x0 126 127 TEXT entrytext(SB),NOSPLIT,$0 128 // u-root-entry-long 129 BYTE $'u'; BYTE $'-'; BYTE $'r'; BYTE $'o'; BYTE $'o'; 130 BYTE $'t'; BYTE $'-'; BYTE $'e'; BYTE $'n'; BYTE $'t'; 131 BYTE $'r'; BYTE $'y'; BYTE $'-'; BYTE $'l'; BYTE $'o'; 132 BYTE $'n'; BYTE $'g'; 133 TEXT entry(SB),NOSPLIT,$0 134 LONG $0x0 135 136 TEXT magictext(SB),NOSPLIT,$0 137 // u-root-mb-magic 138 BYTE $'u'; BYTE $'-'; BYTE $'r'; BYTE $'o'; BYTE $'o'; 139 BYTE $'t'; BYTE $'-'; BYTE $'m'; BYTE $'b'; BYTE $'-'; 140 BYTE $'m'; BYTE $'a'; BYTE $'g'; BYTE $'i'; BYTE $'c'; 141 TEXT magic(SB),NOSPLIT,$0 142 LONG $0x0 143 144 TEXT ·end(SB),NOSPLIT,$0