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';