diff options
author | Tom Cosgrove <tom@cvs.openbsd.org> | 2004-06-23 00:21:50 +0000 |
---|---|---|
committer | Tom Cosgrove <tom@cvs.openbsd.org> | 2004-06-23 00:21:50 +0000 |
commit | 403269453b1c830293bc1c8fbfa081f21e4e2b98 (patch) | |
tree | d05ac43dca988be658f627b979765cd2035546d7 /sys/arch/i386/stand/cdboot/srt0.S | |
parent | 01661f467500349c4597e188579d72fc43e4fa1e (diff) |
Enter cdboot, a CD-specific second-stage bootrap.
Testing krw@ and todd@, thanks.
assistance, testing and ok weingart@
Diffstat (limited to 'sys/arch/i386/stand/cdboot/srt0.S')
-rw-r--r-- | sys/arch/i386/stand/cdboot/srt0.S | 243 |
1 files changed, 243 insertions, 0 deletions
diff --git a/sys/arch/i386/stand/cdboot/srt0.S b/sys/arch/i386/stand/cdboot/srt0.S new file mode 100644 index 00000000000..261191b1e9f --- /dev/null +++ b/sys/arch/i386/stand/cdboot/srt0.S @@ -0,0 +1,243 @@ +/* $OpenBSD: srt0.S,v 1.1 2004/06/23 00:21:49 tom Exp $ */ + +/* + * Copyright (c) 1997 Michael Shalayeff + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ +#include <machine/asm.h> +#include <assym.h> + +#define BOOTSTACK 0xfffc + + .globl _C_LABEL(end) + .globl _C_LABEL(edata) + .globl _C_LABEL(boot) + .globl _C_LABEL(_rtt) + .globl _C_LABEL(bios_bootdev) + .globl _ASM_LABEL(pmm_init) + .globl Gdtr + + .text + .code16 + .globl _start +_start: +#ifdef DEBUG + movl $0xb80a0, %ebx + addr32 movl $0x07420742, (%ebx) +#endif + +/* Clobbers %ax, maybe more */ +#define putc(c) movb $c, %al; call Lchr + + /* + * We operate as a no emulation boot image, as defined by the + * El Torito Bootable CD-ROM Format Specification v1.0. We use + * a load segment of 0x07C0 (physical load address of 0x7C00). + * Like the standard /boot, we are linked to run at 0x40120 + * (load address 0x40000), so we relocate to there. + * + * From 0x7C00 to 0x40000 is 0x38400 (230400) bytes, so don't + * have to worry about an overlapping copy until cdboot is + * over 225 KB. + * + * Note that there are other reasons to be worried if + * sizeof(/boot) > 64 KB. So currently we copy a maximum of 64 KB. + * + * Our cdbr CD-ROM boot sector passes us the drive number to use + * in %dl. + */ +#define CDBOOTADDR 0x7c00 /* Address where BIOS loads up */ + xorw %ax, %ax + movw %ax, %ss /* CPU disables interrupts till... */ + movl $CDBOOTADDR-4, %esp /* after this instruction */ + + movw $(CDBOOTADDR >> 4), %ax + movw %ax, %ds + xorw %si, %si /* Where we're coming from */ + + movw $(LINKADDR >> 4), %ax + movw %ax, %es /* Set %es = 0x4000 */ + xorw %di, %di /* Where we're going to */ + + movl $_C_LABEL(end), %ecx + subl $_C_LABEL(_start), %ecx /* How big are we? */ + + cld + rep; movsb /* Copy into place */ + + jmpl $(LINKADDR >> 4), $(relocated-_start) /* Now relocate */ + +relocated: + /* + * In 16-bit mode, we have segment registers == 0x4012, and + * offsets work from here, with offset(_start) == 0. + * + * In 32-bit mode, we have a flat memory model, where + * offset(_start) == 0x40120. This is how we're linked. + * + * Now transition to protected mode. + * + * First, initialise the global descriptor table. + */ + cli + push %cs + pop %ds + addr32 data32 lgdt (Gdtr - LINKADDR) + + movl %cr0, %eax + orl $CR0_PE, %eax + data32 movl %eax, %cr0 + data32 ljmp $8, $1f /* Seg sel 0x08 is flat 32-bit code */ +1: + .code32 + movl $0x10, %eax /* Seg sel 0x10 is flat 32-bit data */ + mov %ax, %ds + mov %ax, %es + mov %ax, %fs + mov %ax, %gs + mov %ax, %ss + movl $BOOTSTACK, %esp +#ifdef DEBUG + movl $0xb8000, %ebx + movl $0x07420742, (%ebx) +#endif + + movzbl %dl, %eax + orl $0x100, %eax /* Indicate that it's a cd device */ + pushl %eax /* boot() takes this as a parameter */ + + /* Set up an interrupt descriptor table for protected mode. */ + call _ASM_LABEL(pmm_init) +#ifdef DEBUG + movl $0xb80a4, %ebx + movl $0x07520752, (%ebx) +#endif + + /* Zero .bss */ + xorl %eax, %eax + movl $_C_LABEL(end), %ecx + subl $_C_LABEL(edata), %ecx + movl $_C_LABEL(edata), %edi + cld + rep; stosb + + /* Set our program name ("CDBOOT", not "BOOT"). */ + movl $cd_progname, %eax + movl %eax, progname + + /* Put the boot device number into the globals that need it */ + popl %eax /* Get this back from the stack */ + pushl %eax /* boot() takes this as a parameter */ + movl %eax, _C_LABEL(bios_bootdev) + movl %eax, _C_LABEL(bios_cddev) + + /* + * Now call "main()". + * + * We run in flat 32-bit protected mode, with no address mapping. + */ +#ifdef DEBUG + movl $0xb8004, %ebx + movl $0x07410741, (%ebx) +#endif + call _C_LABEL(boot) + + /* boot() should not return. If it does, reset computer. */ + jmp _C_LABEL(_rtt) + +ENTRY(debugchar) + pushl %ebx + movl 8(%esp), %ebx + addl %ebx, %ebx + addl $0xb8000, %ebx + + xorl %eax, %eax + movb 12(%esp), %al + + andl $0xfffffffe, %ebx + movb %al, (%ebx) + popl %ebx + ret + + .code16 + +/* + * Display ASCIZ string at %si. Trashes %si. + */ +Lstr: + pushw %ax + cld +1: + lodsb /* %al = *%si++ */ + testb %al, %al + jz 1f + call Lchr + jmp 1b +1: popw %ax + ret + +/* + * Write out value in %ax in hex + */ +hex_word: + pushw %ax + mov %ah, %al + call hex_byte + popw %ax + /* fall thru */ +/* + * Write out value in %al in hex + */ +hex_byte: + pushw %ax + shrb $4, %al + call hex_nibble + popw %ax + /* fall thru */ + +/* Write out nibble in %al */ +hex_nibble: + and $0x0F, %al + add $'0', %al + cmpb $'9', %al + jbe Lchr + addb $'A'-'9'-1, %al + /* fall thru to Lchr */ +/* + * Lchr: write the character in %al to console + */ +Lchr: + pushw %bx + movb $0x0e, %ah + xorw %bx, %bx + incw %bx /* movw $0x01, %bx */ + int $0x10 + popw %bx + ret + +cd_progname: + .asciz "CDBOOT" + + .end |