1 /* $OpenBSD: srt0.S,v 1.1 2004/06/23 00:21:49 tom Exp $ */ 2 3 /* 4 * Copyright (c) 1997 Michael Shalayeff 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 * 28 */ 29 #include <machine/asm.h> 30 #include <assym.h> 31 32 #define BOOTSTACK 0xfffc 33 34 .globl _C_LABEL(end) 35 .globl _C_LABEL(edata) 36 .globl _C_LABEL(boot) 37 .globl _C_LABEL(_rtt) 38 .globl _C_LABEL(bios_bootdev) 39 .globl _ASM_LABEL(pmm_init) 40 .globl Gdtr 41 42 .text 43 .code16 44 .globl _start 45 _start: 46 #ifdef DEBUG 47 movl $0xb80a0, %ebx 48 addr32 movl $0x07420742, (%ebx) 49 #endif 50 51 /* Clobbers %ax, maybe more */ 52 #define putc(c) movb $c, %al; call Lchr 53 54 /* 55 * We operate as a no emulation boot image, as defined by the 56 * El Torito Bootable CD-ROM Format Specification v1.0. We use 57 * a load segment of 0x07C0 (physical load address of 0x7C00). 58 * Like the standard /boot, we are linked to run at 0x40120 59 * (load address 0x40000), so we relocate to there. 60 * 61 * From 0x7C00 to 0x40000 is 0x38400 (230400) bytes, so don't 62 * have to worry about an overlapping copy until cdboot is 63 * over 225 KB. 64 * 65 * Note that there are other reasons to be worried if 66 * sizeof(/boot) > 64 KB. So currently we copy a maximum of 64 KB. 67 * 68 * Our cdbr CD-ROM boot sector passes us the drive number to use 69 * in %dl. 70 */ 71 #define CDBOOTADDR 0x7c00 /* Address where BIOS loads up */ 72 xorw %ax, %ax 73 movw %ax, %ss /* CPU disables interrupts till... */ 74 movl $CDBOOTADDR-4, %esp /* after this instruction */ 75 76 movw $(CDBOOTADDR >> 4), %ax 77 movw %ax, %ds 78 xorw %si, %si /* Where we're coming from */ 79 80 movw $(LINKADDR >> 4), %ax 81 movw %ax, %es /* Set %es = 0x4000 */ 82 xorw %di, %di /* Where we're going to */ 83 84 movl $_C_LABEL(end), %ecx 85 subl $_C_LABEL(_start), %ecx /* How big are we? */ 86 87 cld 88 rep; movsb /* Copy into place */ 89 90 jmpl $(LINKADDR >> 4), $(relocated-_start) /* Now relocate */ 91 92 relocated: 93 /* 94 * In 16-bit mode, we have segment registers == 0x4012, and 95 * offsets work from here, with offset(_start) == 0. 96 * 97 * In 32-bit mode, we have a flat memory model, where 98 * offset(_start) == 0x40120. This is how we're linked. 99 * 100 * Now transition to protected mode. 101 * 102 * First, initialise the global descriptor table. 103 */ 104 cli 105 push %cs 106 pop %ds 107 addr32 data32 lgdt (Gdtr - LINKADDR) 108 109 movl %cr0, %eax 110 orl $CR0_PE, %eax 111 data32 movl %eax, %cr0 112 data32 ljmp $8, $1f /* Seg sel 0x08 is flat 32-bit code */ 113 1: 114 .code32 115 movl $0x10, %eax /* Seg sel 0x10 is flat 32-bit data */ 116 mov %ax, %ds 117 mov %ax, %es 118 mov %ax, %fs 119 mov %ax, %gs 120 mov %ax, %ss 121 movl $BOOTSTACK, %esp 122 #ifdef DEBUG 123 movl $0xb8000, %ebx 124 movl $0x07420742, (%ebx) 125 #endif 126 127 movzbl %dl, %eax 128 orl $0x100, %eax /* Indicate that it's a cd device */ 129 pushl %eax /* boot() takes this as a parameter */ 130 131 /* Set up an interrupt descriptor table for protected mode. */ 132 call _ASM_LABEL(pmm_init) 133 #ifdef DEBUG 134 movl $0xb80a4, %ebx 135 movl $0x07520752, (%ebx) 136 #endif 137 138 /* Zero .bss */ 139 xorl %eax, %eax 140 movl $_C_LABEL(end), %ecx 141 subl $_C_LABEL(edata), %ecx 142 movl $_C_LABEL(edata), %edi 143 cld 144 rep; stosb 145 146 /* Set our program name ("CDBOOT", not "BOOT"). */ 147 movl $cd_progname, %eax 148 movl %eax, progname 149 150 /* Put the boot device number into the globals that need it */ 151 popl %eax /* Get this back from the stack */ 152 pushl %eax /* boot() takes this as a parameter */ 153 movl %eax, _C_LABEL(bios_bootdev) 154 movl %eax, _C_LABEL(bios_cddev) 155 156 /* 157 * Now call "main()". 158 * 159 * We run in flat 32-bit protected mode, with no address mapping. 160 */ 161 #ifdef DEBUG 162 movl $0xb8004, %ebx 163 movl $0x07410741, (%ebx) 164 #endif 165 call _C_LABEL(boot) 166 167 /* boot() should not return. If it does, reset computer. */ 168 jmp _C_LABEL(_rtt) 169 170 ENTRY(debugchar) 171 pushl %ebx 172 movl 8(%esp), %ebx 173 addl %ebx, %ebx 174 addl $0xb8000, %ebx 175 176 xorl %eax, %eax 177 movb 12(%esp), %al 178 179 andl $0xfffffffe, %ebx 180 movb %al, (%ebx) 181 popl %ebx 182 ret 183 184 .code16 185 186 /* 187 * Display ASCIZ string at %si. Trashes %si. 188 */ 189 Lstr: 190 pushw %ax 191 cld 192 1: 193 lodsb /* %al = *%si++ */ 194 testb %al, %al 195 jz 1f 196 call Lchr 197 jmp 1b 198 1: popw %ax 199 ret 200 201 /* 202 * Write out value in %ax in hex 203 */ 204 hex_word: 205 pushw %ax 206 mov %ah, %al 207 call hex_byte 208 popw %ax 209 /* fall thru */ 210 /* 211 * Write out value in %al in hex 212 */ 213 hex_byte: 214 pushw %ax 215 shrb $4, %al 216 call hex_nibble 217 popw %ax 218 /* fall thru */ 219 220 /* Write out nibble in %al */ 221 hex_nibble: 222 and $0x0F, %al 223 add $'0', %al 224 cmpb $'9', %al 225 jbe Lchr 226 addb $'A'-'9'-1, %al 227 /* fall thru to Lchr */ 228 /* 229 * Lchr: write the character in %al to console 230 */ 231 Lchr: 232 pushw %bx 233 movb $0x0e, %ah 234 xorw %bx, %bx 235 incw %bx /* movw $0x01, %bx */ 236 int $0x10 237 popw %bx 238 ret 239 240 cd_progname: 241 .asciz "CDBOOT" 242 243 .end