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