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 lgdtl gdt_desc - _start + 0x10 49 50 # enable sse and pae 51 mov $0x620, %eax 52 mov %eax, %cr4 53 54 # enable long mode by setting EFER 55 mov $0x100, %eax 56 xor %edx, %edx 57 mov $0xc0000080, %ecx 58 wrmsr 59 60 # set the page table base address 61 mov $level4pt, %eax 62 mov %eax, %cr3 63 64 # enable paging and protected mode by setting PG and PE 65 mov $0x80000001, %eax 66 mov %eax, %cr0 67 68 ljmpl $0x10,$_start64 69 70 .code64 71_start64: 72 mov $0x18, %eax # selector for 32-bit data segment 73 mov %eax, %es # propagate to all data segments 74 mov %eax, %ss 75 mov %eax, %ds 76 mov %eax, %fs 77 mov %eax, %gs 78 79 /* Initialize the stack */ 80 mov $__stack, %esp 81 82 /* Initialize data segment */ 83 mov $__data_size, %rdx 84 mov $__data_source, %rsi 85 mov $__data_start, %rdi 86 call memcpy 87 88 /* Initialize BSS */ 89 mov $__bss_size, %rdx 90 mov $0, %rsi 91 mov $__bss_start, %rdi 92 call memset 93 94#ifdef PICOLIBC_TLS 95 // call to _set_tls(__tls_base) 96 mov $__tls_base, %rdi 97 call _set_tls 98#endif 99 100#if defined(_HAVE_INITFINI_ARRAY) && CONSTRUCTORS 101 call __libc_init_array 102#endif 103 104 mov $0, %rdi 105 mov $0, %rsi 106 mov $0, %rdx 107 call main 108 109#ifdef CRT0_EXIT 110 mov %rax, %rdi 111 call exit 112#else 1131: 114 jmp 1b 115#endif 116 117gdt_desc: 118 .word gdt_end - gdt - 1 119 .long gdt 120 121gdt: 122 .quad 0x0000000000000000 # unused (null selector) 123 .quad 0x0000000000000000 # 0x08: space for Task State Segment 124 .quad 0x00AF9B000000FFFF # 0x10: ring 0 64-bit code segment 125 .quad 0x00CF93000000FFFF # 0x18: ring 0 data segment 126gdt_end: 127 128 .section .rodata 129 /* Page table */ 130 .balign 4096, 0 131level4pt: 132 .quad level3pt + 0x67 133 .balign 4096, 0 134level3pt: 135 .quad level2pt + 0x67 136 .balign 4096, 0 137level2pt: 138#define page1(base) \ 139 ((0x00000000000000E7) | ((base) << 21)) 140#define page2(base) \ 141 page1(base), \ 142 page1((base)+1) 143#define page4(base) \ 144 page2(base), \ 145 page2((base)+2) 146#define page8(base) \ 147 page4(base), \ 148 page4((base)+4) 149#define page16(base) \ 150 page8(base), \ 151 page8((base)+8) 152#define page32(base) \ 153 page16(base), \ 154 page16((base)+16) 155#define page32(base) \ 156 page16(base), \ 157 page16((base)+16) 158#define page64(base) \ 159 page32(base), \ 160 page32((base)+32) 161#define page128(base) \ 162 page64(base), \ 163 page64((base)+64) 164#define page256(base) \ 165 page128(base), \ 166 page128((base)+128) 167#define page512(base) \ 168 page256(base), \ 169 page256((base)+256) 170 .quad page512(0) 171 172#if defined(__linux__) && defined(__ELF__) 173.section .note.GNU-stack,"",%progbits 174#endif 175