/* -----------------------------------------------------------------------
*
- * Copyright 2007 H. Peter Anvin - All Rights Reserved
+ * Copyright 2007-2009 H. Peter Anvin - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author: H. Peter Anvin
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
*
* ----------------------------------------------------------------------- */
+#include "adjust.h"
+
.code16
.text
sectors = (stack-8)
secpercyl = (stack-12)
-BIOS_page = 0x462
+BIOS_kbdflags = 0x417
+BIOS_page = 0x462
/* gas/ld has issues with doing this as absolute addresses... */
.section ".bootsec", "a", @nobits
.text
.globl _start
_start:
+ .byte 0x33, 0xc0 /* xorw %ax, %ax */
cli
- xorw %ax, %ax
movw %ax, %ds
movw %ax, %ss
movw $stack, %sp
movw %sp, %si
pushw %es /* es:di -> $PnP header */
pushw %di
- pushw %dx /* dl -> drive number */
movw %ax, %es
sti
cld
rep; movsw
ljmpw $0, $next
-
next:
+
+ ADJUST_DRIVE
+ pushw %dx /* dl -> drive number */
+
/* Check to see if we have EBIOS */
pushw %dx /* drive number */
- movw $0x4100, %ax
+ movb $0x41, %ah /* %al == 0 already */
movw $0x55aa, %bx
xorw %cx, %cx
xorb %dh, %dh
int $0x13
andw $0x3f, %cx /* Sector count */
pushw %cx /* Save sectors on the stack */
- xorw %ax, %ax
- pushw %ax /* High word of sectors/cylinder */
- movb %dh, %al /* dh = number of heads */
- incw %ax /* From 0-based to count */
+ movzbw %dh, %ax /* dh = max head */
+ incw %ax /* From 0-based max to count */
mulw %cx /* Heads*sectors -> sectors per cylinder */
- pushw %ax /* Save sectors/cylinder on the stack */
+
+ /* Save sectors/cylinder on the stack */
+ pushw %dx /* High word */
+ pushw %ax /* Low word */
xorl %eax, %eax /* Base */
cdq /* Root (%edx <- 0) */
call scan_partition_table
/* If we get here, we have no OS */
- jmp missing_os
+missing_os:
+ call error
+ .ascii "Missing operating system.\r\n"
/*
* read_sector: read a single sector pointed to by %eax to 0x7c00.
/* This chunk is skipped if we have ebios */
/* Do not clobber %eax before this chunk! */
+ /* This also relies on %bx and %edx as set up above. */
read_sector_cbios:
divl (secpercyl)
shlb $6, %ah
read_common:
movb (driveno), %dl
int $0x13
- addw $16, %sp /* Drop DAPA */
+ leaw 16(%si), %sp /* Drop DAPA */
popal
ret
jns too_many_active
/* No active partitions found, look for extended partitions */
- popw %bx /* %bx <- ptab */
popw %cx /* %cx <- 4 */
+ popw %bx /* %bx <- ptab */
7:
movb 4(%bx), %al
cmpb $0x0f, %al /* 0x0f = Win9x extended */
popal
ret
+too_many_active:
+ call error
+ .ascii "Multiple active partitions.\r\n"
+
/*
* boot: invoke the actual bootstrap. (%si) points to the partition
* table entry, and 28(%bp) has the partition table base.
jc disk_error
cmpw $0xaa55, (bootsec+510)
jne missing_os /* Not a valid boot sector */
- movw $driveno, %sp
+ movw $driveno, %sp /* driveno == bootsec-6 */
popw %dx /* dl -> drive number */
popw %di /* es:di -> $PnP vector */
popw %es
cli
- jmp bootsec
+ jmpw *%sp /* %sp == bootsec */
-/*
- * error messages
- */
-missing_os:
- movw $missing_os_msg, %si
- jmp error
disk_error:
- movw $disk_error_msg, %si
- jmp error
-too_many_active:
- movw $too_many_active_msg, %si
- /* jmp error */
+ call error
+ .ascii "Operating system load error.\r\n"
+/*
+ * Print error messages. This is invoked with "call", with the
+ * error message at the return address.
+ */
error:
+ popw %si
2:
lodsb
- andb %al, %al
- jz 3f
movb $0x0e, %ah
movb (BIOS_page), %bh
movb $0x07, %bl
- int $0x10
- jmp 2b
-3:
- int $0x18 /* Boot failure */
- jmp . /* Die */
+ int $0x10 /* May destroy %bp */
+ cmpb $10, %al /* Newline? */
+ jne 2b
-missing_os_msg:
- .ascii "Missing operating system.\r\n"
- .byte 0
-disk_error_msg:
- .ascii "Operating system load error.\r\n"
- .byte 0
-too_many_active_msg:
- .ascii "Multiple active partitions.\r\n"
- .byte 0
+ int $0x18 /* Boot failure */
+die:
+ hlt
+ jmp die