github.com/shaardie/u-root@v4.0.1-0.20190127173353-f24a1c26aa2e+incompatible/pkg/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 #define MAGIC 0x2BADB002 20 21 TEXT begin(SB),NOSPLIT,$0 22 // u-root-trampoline-begin 23 BYTE $'u'; BYTE $'-'; BYTE $'r'; BYTE $'o'; BYTE $'o'; 24 BYTE $'t'; BYTE $'-'; BYTE $'t'; BYTE $'r'; BYTE $'a'; 25 BYTE $'m'; BYTE $'p'; BYTE $'o'; BYTE $'l'; BYTE $'i'; 26 BYTE $'n'; BYTE $'e'; BYTE $'-'; BYTE $'b'; BYTE $'e'; 27 BYTE $'g'; BYTE $'i'; BYTE $'n'; 28 29 TEXT ·start(SB),NOSPLIT,$0 30 // Create GDT pointer on stack. 31 LEAQ gdt(SB), CX 32 SHLQ $16, CX 33 ORQ $(4*8 - 1), CX 34 PUSHQ CX 35 36 LGDT (SP) 37 38 // Store value of multiboot info addr in BX. 39 // Don't modify BX. 40 MOVL info(SB), BX 41 42 // Far return doesn't work on QEMU in 64-bit mode, 43 // let's do far jump. 44 // 45 // In a regular plan9 assembly we can do something like: 46 // BYTE $0xFF; BYTE $0x2D 47 // LONG $bootaddr(SB) 48 // TEXT bootaddr(SB),NOSPLIT,$0 49 // LONG $boot(SB) 50 // LONG $0x8 51 // 52 // Go compiler doesn't let us do it. 53 // 54 // Setup offset to make a far jump from boot(SB) 55 // to a final kernel in a 32-bit mode. 56 MOVL entry(SB), AX 57 MOVL AX, farjump32+1(SB) 58 59 // Setup offset to make a far jump to boot(SB) 60 // to switch from 64-bit mode to 32-bit mode. 61 LEAQ boot(SB), CX 62 MOVL CX, farjump64+6(SB) 63 JMP farjump64(SB) 64 65 66 TEXT boot(SB),NOSPLIT,$0 67 // We are in 32-bit mode now. 68 // 69 // Be careful editing this code!!! Go compiler 70 // interprets all commands as 64-bit commands. 71 72 // Disable paging. 73 MOVL CR0, AX 74 ANDL $CR0_PG, AX 75 MOVL AX, CR0 76 77 // Disable long mode. 78 MOVL $MSR_EFER, CX 79 RDMSR 80 ANDL $EFER_LME, AX 81 WRMSR 82 83 // Disable PAE. 84 XORL AX, AX 85 MOVL AX, CR4 86 87 // Load data segments. 88 MOVL $0x10, AX // GDT 0x10 data segment 89 BYTE $0x8e; BYTE $0xd8 // MOVL AX, DS 90 BYTE $0x8e; BYTE $0xc0 // MOVL AX, ES 91 BYTE $0x8e; BYTE $0xd0 // MOVL AX, SS 92 BYTE $0x8e; BYTE $0xe0 // MOVL AX, FS 93 BYTE $0x8e; BYTE $0xe8 // MOVL AX, GS 94 95 MOVL $MAGIC, AX 96 JMP farjump32(SB) 97 98 // Unreachable code. 99 // Need reference text labels for compiler to 100 // include them to a binary. 101 JMP begin(SB) 102 JMP infotext(SB) 103 JMP entrytext(SB) 104 JMP end(SB) 105 106 TEXT farjump64(SB),NOSPLIT,$0 107 BYTE $0xFF; BYTE $0x2D; LONG $0x0 // ljmp *(ip) 108 109 LONG $0x0 // farjump64+6(SB) 110 LONG $0x8 // code segment 111 112 TEXT farjump32(SB),NOSPLIT,$0 113 // ljmp $0x18, offset 114 BYTE $0xEA 115 LONG $0x0 // farjump32+1(SB) 116 WORD $0x18 // code segment 117 118 TEXT gdt(SB),NOSPLIT,$0 119 QUAD $0x0 // 0x0 null entry 120 QUAD $CODE_SEGMENT // 0x8 121 QUAD $DATA_SEGMENT // 0x10 122 QUAD $CODE_SEGMENT // 0x18 123 124 TEXT infotext(SB),NOSPLIT,$0 125 // u-root-info-long 126 BYTE $'u'; BYTE $'-'; BYTE $'r'; BYTE $'o'; BYTE $'o'; 127 BYTE $'t'; BYTE $'-'; BYTE $'i'; BYTE $'n'; BYTE $'f'; 128 BYTE $'o'; BYTE $'-'; BYTE $'l'; BYTE $'o'; BYTE $'n'; 129 BYTE $'g'; 130 TEXT info(SB),NOSPLIT,$0 131 LONG $0x0 132 133 TEXT entrytext(SB),NOSPLIT,$0 134 // u-root-entry-long 135 BYTE $'u'; BYTE $'-'; BYTE $'r'; BYTE $'o'; BYTE $'o'; 136 BYTE $'t'; BYTE $'-'; BYTE $'e'; BYTE $'n'; BYTE $'t'; 137 BYTE $'r'; BYTE $'y'; BYTE $'-'; BYTE $'l'; BYTE $'o'; 138 BYTE $'n'; BYTE $'g'; 139 TEXT entry(SB),NOSPLIT,$0 140 LONG $0x0 141 142 TEXT end(SB),NOSPLIT,$0 143 // u-root-trampoline-end 144 BYTE $'u'; BYTE $'-'; BYTE $'r'; BYTE $'o'; BYTE $'o'; 145 BYTE $'t'; BYTE $'-'; BYTE $'t'; BYTE $'r'; BYTE $'a'; 146 BYTE $'m'; BYTE $'p'; BYTE $'o'; BYTE $'l'; BYTE $'i'; 147 BYTE $'n'; BYTE $'e'; BYTE $'-'; BYTE $'e'; BYTE $'n'; 148 BYTE $'d';