176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* -----------------------------------------------------------------------
276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *   Copyright 2007-2009 H. Peter Anvin - All Rights Reserved
476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *   Copyright 2009 Intel Corporation; author: H. Peter Anvin
576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *   Permission is hereby granted, free of charge, to any person
776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *   obtaining a copy of this software and associated documentation
876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *   files (the "Software"), to deal in the Software without
976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *   restriction, including without limitation the rights to use,
1076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *   copy, modify, merge, publish, distribute, sublicense, and/or
1176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *   sell copies of the Software, and to permit persons to whom
1276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *   the Software is furnished to do so, subject to the following
1376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *   conditions:
1476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
1576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *   The above copyright notice and this permission notice shall
1676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *   be included in all copies or substantial portions of the Software.
1776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
1876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
1976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
2076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
2176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
2276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
2376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
2476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
2576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *   OTHER DEALINGS IN THE SOFTWARE.
2676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
2776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * ----------------------------------------------------------------------- */
2876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
2976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include "adjust.h"
3076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
3176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.code16
3276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.text
3376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
3476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.globl	bootsec
3576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstack		= 0x7c00
3676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmandriveno		= (stack-6)
3776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmansectors		= (stack-8)
3876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmansecpercyl	= (stack-12)
3976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
4076d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanBIOS_kbdflags	= 0x417
4176d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanBIOS_page	= 0x462
4276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
4376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* gas/ld has issues with doing this as absolute addresses... */
4476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.section ".bootsec", "a", @nobits
4576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.globl	bootsec
4676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanbootsec:
4776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.space	512
4876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
4976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.text
5076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.globl	_start
5176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman_start:
5276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.byte	0x33, 0xc0	/* xorw	%ax, %ax */
5376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	cli
5476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	%ax, %ds
5576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	%ax, %ss
5676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	$stack, %sp
5776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	%sp, %si
5876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	pushw	%es		/* es:di -> $PnP header */
5976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	pushw	%di
6076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	%ax, %es
6176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	sti
6276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	cld
6376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
6476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Copy down to 0:0x600 */
6576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	$_start, %di
6676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	$(512/2), %cx
6776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	rep; movsw
6876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
6976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	ljmpw	$0, $next
7076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmannext:
7176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
7276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	ADJUST_DRIVE
7376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	pushw	%dx		/* dl -> drive number */
7476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
7576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Check to see if we have EBIOS */
7676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	pushw	%dx		/* drive number */
7776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movb	$0x41, %ah	/* %al == 0 already */
7876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	$0x55aa, %bx
7976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	xorw	%cx, %cx
8076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	xorb	%dh, %dh
8176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	stc
8276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int	$0x13
8376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	jc	1f
8476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	cmpw	$0xaa55, %bx
8576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	jne	1f
8676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	shrw	%cx		/* Bit 0 = fixed disk subset */
8776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	jnc	1f
8876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
8976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* We have EBIOS; patch in the following code at
9076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	   read_sector_cbios: movb $0x42, %ah ;  jmp read_common */
9176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movl	$0xeb42b4+((read_common-read_sector_cbios-4) << 24), \
9276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		(read_sector_cbios)
9376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
9476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman1:
9576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	popw	%dx
9676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
9776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Get (C)HS geometry */
9876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movb	$0x08, %ah
9976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int	$0x13
10076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	andw	$0x3f, %cx	/* Sector count */
10176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	pushw	%cx		/* Save sectors on the stack */
10276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movzbw	%dh, %ax	/* dh = max head */
10376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	incw	%ax		/* From 0-based max to count */
10476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	mulw	%cx		/* Heads*sectors -> sectors per cylinder */
10576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
10676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Save sectors/cylinder on the stack */
10776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	pushw	%dx		/* High word */
10876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	pushw	%ax		/* Low word */
10976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
11076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	xorl	%eax, %eax	/* Base */
11176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	cdq			/* Root (%edx <- 0) */
11276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	call	scan_partition_table
11376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
11476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* If we get here, we have no OS */
11576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanmissing_os:
11676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	call	error
11776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.ascii	"Missing operating system.\r\n"
11876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
11976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/*
12076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * read_sector: read a single sector pointed to by %eax to 0x7c00.
12176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * CF is set on error.  All registers saved.
12276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
12376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanread_sector:
12476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	pushal
12576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	xorl	%edx, %edx
12676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	$bootsec, %bx
12776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	pushl	%edx	/* MSW of LBA */
12876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	pushl	%eax	/* LSW of LBA */
12976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	pushw	%es	/* Buffer segment */
13076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	pushw	%bx	/* Buffer offset */
13176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	pushw	$1	/* Sector count */
13276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	pushw	$16	/* Size of packet */
13376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	%sp, %si
13476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
13576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* This chunk is skipped if we have ebios */
13676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Do not clobber %eax before this chunk! */
13776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* This also relies on %bx and %edx as set up above. */
13876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanread_sector_cbios:
13976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	divl	(secpercyl)
14076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	shlb	$6, %ah
14176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movb	%ah, %cl
14276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movb	%al, %ch
14376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	xchgw	%dx, %ax
14476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	divb	(sectors)
14576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movb	%al, %dh
14676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	orb	%ah, %cl
14776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	incw	%cx	/* Sectors are 1-based */
14876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	$0x0201, %ax
14976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
15076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanread_common:
15176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movb	(driveno), %dl
15276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int	$0x13
15376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	leaw	16(%si), %sp	/* Drop DAPA */
15476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	popal
15576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	ret
15676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
15776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/*
15876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * read_partition_table:
15976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *	Read a partition table (pointed to by %eax), and copy
16076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *	the partition table into the ptab buffer.
16176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
16276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *	Clobbers %si, %di, and %cx, other registers preserved.
16376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *	%cx = 0 on exit.
16476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
16576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *	On error, CF is set and ptab is overwritten with junk.
16676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
16776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanptab	= _start+446
16876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
16976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanread_partition_table:
17076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	call	read_sector
17176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	$bootsec+446, %si
17276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	$ptab, %di
17376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	$(16*4/2), %cx
17476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	rep ; movsw
17576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	ret
17676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
17776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/*
17876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * scan_partition_table:
17976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *	Scan a partition table currently loaded in the partition table
18076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *	area.  Preserve all registers.
18176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
18276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *      On entry:
18376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *	  %eax - base (location of this partition table)
18476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *	  %edx - root (offset from MBR, or 0 for MBR)
18576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
18676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *      These get pushed into stack slots:
18776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *        28(%bp) - %eax - base
18876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *	  20(%bp) - %edx - root
18976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
19076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
19176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanscan_partition_table:
19276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	pushal
19376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	%sp, %bp
19476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
19576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Scan the primary partition table */
19676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	$ptab, %si
19776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	$4, %cx
19876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Is it a primary partition table? */
19976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	andl	%edx, %edx
20076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	jnz	7f
20176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	push	%si
20276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	push	%cx
20376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
20476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman5:
20576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	decb	(partition)
20676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	jz	boot
20776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	addw	$16, %si
20876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	loopw	5b
20976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
21076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	popw	%cx			/* %cx <- 4    */
21176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	popw	%si			/* %si <- ptab */
21276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
21376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* No primary partitions found, look for extended/logical partitions */
21476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman7:
21576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movb	4(%si), %al
21676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	andb	%al, %al
21776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	jz	12f			/* Not a valid partition */
21876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	cmpb	$0x0f, %al		/* 0x0f = Win9x extended */
21976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	je	8f
22076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	andb	$~0x80, %al		/* 0x85 = Linux extended */
22176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	cmpb	$0x05, %al		/* 0x05 = MS-DOS extended */
22276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	jne	9f
22376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
22476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* It is an extended partition.  Read the extended partition and
22576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	   try to scan it.  If the scan returns, re-load the current
22676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	   partition table and resume scan. */
22776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman8:
22876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movl	8(%si), %eax		/* Partition table offset */
22976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	addl	%edx, %eax		/* Compute location of new ptab */
23076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	andl	%edx, %edx		/* Is this the MBR? */
23176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	jnz	10f
23276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movl	%eax, %edx		/* Offset -> root if this was MBR */
23376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman10:
23476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	call	read_partition_table
23576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	jc	11f
23676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	call	scan_partition_table
23776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman11:
23876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* This returned, so we need to reload the current partition table */
23976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movl	28(%bp), %eax		/* "Base" */
24076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	call	read_partition_table
24176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
24276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* fall through */
24376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman9:
24476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Not an extended partition */
24576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	andl	%edx, %edx		/* Are we inside an extended part? */
24676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	jz	12f
24776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* If so, this is a logical partition */
24876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	decb	(partition)
24976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	je	boot
25076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman12:
25176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	addw	$16, %si
25276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	loopw	7b
25376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
25476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Nothing found, return */
25576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	popal
25676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	ret
25776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
25876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/*
25976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * boot: invoke the actual bootstrap. (%si) points to the partition
26076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *	 table entry, and 28(%bp) has the partition table base.
26176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
26276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanboot:
26376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	cmpb	$0, 4(%si)
26476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	je	missing_os
26576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movl	8(%si), %eax
26676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	addl	28(%bp), %eax
26776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movl	%eax, 8(%si)	/* Adjust in-memory partition table entry */
26876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	call	read_sector
26976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	jc	disk_error
27076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	cmpw	$0xaa55, (bootsec+510)
27176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	jne	missing_os		/* Not a valid boot sector */
27276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	$driveno, %sp	/* driveno == bootsec-6 */
27376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	popw	%dx		/* dl -> drive number */
27476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	popw	%di		/* es:di -> $PnP vector */
27576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	popw	%es
27676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	cli
27776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	jmpw	*%sp		/* %sp == bootsec */
27876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
27976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmandisk_error:
28076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	call	error
28176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.ascii	"Operating system load error.\r\n"
28276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
28376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/*
28476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Print error messages.  This is invoked with "call", with the
28576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * error message at the return address.
28676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
28776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanerror:
28876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	popw	%si
28976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman2:
29076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	lodsb
29176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movb	$0x0e, %ah
29276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movb	(BIOS_page), %bh
29376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movb	$0x07, %bl
29476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int	$0x10		/* May destroy %bp */
29576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	cmpb	$10, %al	/* Newline? */
29676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	jne	2b
29776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
29876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int	$0x18		/* Boot failure */
29976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmandie:
30076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	hlt
30176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	jmp	die
30276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
30376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Location of the partition configuration byte */
30476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanpartition = _start + 439
305