1/* 2 * SPDX-License-Identifier: BSD-3-Clause 3 * 4 * Copyright © 2021 Mike Haertel and Keith Packard 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 13 * 2. Redistributions in binary form must reproduce the above 14 * copyright notice, this list of conditions and the following 15 * disclaimer in the documentation and/or other materials provided 16 * with the distribution. 17 * 18 * 3. Neither the name of the copyright holder nor the names of its 19 * contributors may be used to endorse or promote products derived 20 * from this software without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 25 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 26 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 27 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 28 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 29 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 31 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 33 * OF THE POSSIBILITY OF SUCH DAMAGE. 34 */ 35 36#include <picolibc.h> 37 38#ifndef CONSTRUCTORS 39#define CONSTRUCTORS 1 40#endif 41 42 .text 43 .section .text.init.enter 44 .globl _start 45 .type start, @function 46_start: 47 .code16 48 cs 49 lgdtl gdt_desc - _start + 0x10 50 51 # enable sse and pae 52 mov $0x620, %eax 53 mov %eax, %cr4 54 55 # enable long mode by setting EFER 56 mov $0x100, %eax 57 xor %edx, %edx 58 mov $0xc0000080, %ecx 59 wrmsr 60 61 # set the page table base address 62 mov $level4pt, %eax 63 mov %eax, %cr3 64 65 # enable paging and protected mode by setting PG and PE 66 mov $0x80000001, %eax 67 mov %eax, %cr0 68 69 ljmpl $0x10,$_start64 70 71 .code64 72_start64: 73 mov $0x18, %eax # selector for 32-bit data segment 74 mov %eax, %es # propagate to all data segments 75 mov %eax, %ss 76 mov %eax, %ds 77 mov %eax, %fs 78 mov %eax, %gs 79 80 /* Initialize the stack */ 81 mov $__stack, %esp 82 83 /* Initialize data segment */ 84 mov $__data_size, %rdx 85 mov $__data_source, %rsi 86 mov $__data_start, %rdi 87 call memcpy 88 89 /* Initialize BSS */ 90 mov $__bss_size, %rdx 91 mov $0, %rsi 92 mov $__bss_start, %rdi 93 call memset 94 95#ifdef PICOLIBC_TLS 96 // call to _set_tls(__tls_base) 97 mov $__tls_base, %rdi 98 call _set_tls 99#endif 100 101#if defined(_HAVE_INITFINI_ARRAY) && CONSTRUCTORS 102 call __libc_init_array 103#endif 104 105 mov $0, %rdi 106 mov $0, %rsi 107 mov $0, %rdx 108 call main 109 110#ifdef CRT0_EXIT 111 mov %rax, %rdi 112 call exit 113#else 1141: 115 jmp 1b 116#endif 117 118gdt_desc: 119 .word gdt_end - gdt - 1 120 .long gdt 121 122gdt: 123 .quad 0x0000000000000000 # unused (null selector) 124 .quad 0x0000000000000000 # 0x08: space for Task State Segment 125 .quad 0x00AF9B000000FFFF # 0x10: ring 0 64-bit code segment 126 .quad 0x00CF93000000FFFF # 0x18: ring 0 data segment 127gdt_end: 128 129 .section .rodata 130 /* Page table */ 131 .balign 4096, 0 132level4pt: 133 .quad level3pt + 0x67 134 .balign 4096, 0 135level3pt: 136 .quad level2pt + 0x67 137 .balign 4096, 0 138level2pt: 139#define page1(base) \ 140 ((0x00000000000000E7) | ((base) << 21)) 141#define page2(base) \ 142 page1(base), \ 143 page1((base)+1) 144#define page4(base) \ 145 page2(base), \ 146 page2((base)+2) 147#define page8(base) \ 148 page4(base), \ 149 page4((base)+4) 150#define page16(base) \ 151 page8(base), \ 152 page8((base)+8) 153#define page32(base) \ 154 page16(base), \ 155 page16((base)+16) 156#define page32(base) \ 157 page16(base), \ 158 page16((base)+16) 159#define page64(base) \ 160 page32(base), \ 161 page32((base)+32) 162#define page128(base) \ 163 page64(base), \ 164 page64((base)+64) 165#define page256(base) \ 166 page128(base), \ 167 page128((base)+128) 168#define page512(base) \ 169 page256(base), \ 170 page256((base)+256) 171 .quad page512(0) 172 173#if defined(__linux__) && defined(__ELF__) 174.section .note.GNU-stack,"",%progbits 175#endif 176