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/*
3076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Modified MBR code used on an ISO image in hybrid mode.
3176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
3276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * This doesn't follow the El Torito spec at all -- it is just a stub
3376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * loader of a hard-coded offset, but that's good enough to load
3476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * ISOLINUX.
3576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
3676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
3776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include "adjust.h"
3876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
3976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.code16
4076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.text
4176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
4276d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanHYBRID_MAGIC			= 0x7078c0fb
4376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanisolinux_hybrid_signature	= 0x7c00+64
4476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanisolinux_start_hybrid		= 0x7c00+64+4
4576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
4676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.globl	bootsec
4776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Important: the top 6 words on the stack are passed to isolinux.bin */
4876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstack		= 0x7c00
4976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanpartoffset	= (stack-8)
5076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmandriveno		= (stack-14)
5176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanheads		= (stack-16)
5276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmansectors		= (stack-18)
5376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanebios_flag	= (stack-20)
5476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmansecpercyl	= (stack-24)
5576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
5676d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanBIOS_kbdflags	= 0x417
5776d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanBIOS_page	= 0x462
5876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
5976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* gas/ld has issues with doing this as absolute addresses... */
6076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.section ".bootsec", "a", @nobits
6176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.globl	bootsec
6276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanbootsec:
6376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.space	512
6476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
6576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.text
6676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.globl	_start
6776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman_start:
6876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.byte	0x33, 0xed	/* xorw	%bp, %bp */
6976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	nop
7076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	nop
7176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	nop
7276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	nop
7376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	nop
7476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	nop
7576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	nop
7676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	nop
7776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	nop
7876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	nop
7976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	nop
8076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	nop
8176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	nop
8276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	nop
8376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	nop
8476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	nop
8576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	nop
8676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	nop
8776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	nop
8876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	nop
8976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	nop
9076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	nop
9176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	nop
9276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	nop
9376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	nop
9476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	nop
9576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	nop
9676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	nop
9776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	nop
9876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	nop
9976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.byte	0x33, 0xed	/* xorw	%bp, %bp */
10076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	cli
10176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	%bp, %ss
10276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	$stack, %sp
10376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	sti
10476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	cld
10576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
10676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Check to see if we have a partition table entry */
10776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	xorl	%ebx, %ebx
10876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	xorl	%ecx, %ecx
10976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PARTITION_SUPPORT
11076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	andw	%si, %si		/* %si == 0 -> no partition data */
11176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	jz	1f
11276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	testb	$0x7f, (%si)		/* Invalid active flag field? */
11376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	jnz	1f
11476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	cmpb	%cl, 4(%si)		/* Partition type zero == invalid? */
11576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	je	1f
11676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	cmpl	$0x58504721, %eax	/* !GPT signature in EAX? */
11776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	jne	2f
11876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	cmpb	$0xed, 4(%si)		/* EFI partition type? */
11976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	jne	2f
12076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
12176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* We have GPT partition information */
12276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movl	(32+20)(%si), %ecx
12376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movl	(36+20)(%si), %ebx
12476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	jmp	1f
12576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
12676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* We have non-GPT partition information */
12776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman2:
12876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movl	8(%si), %ecx
12976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
13076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman1:
13176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* We have no partition information */
13276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	pushl	%ebx			/*  -4: partoffset_hi */
13376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	pushl	%ecx			/*  -8: partoffset_lo */
13476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	pushw	%es			/* -10: es:di -> $PnP header */
13576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	pushw	%di			/* -12: es:di -> $PnP header */
13676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
13776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	%bp, %ds
13876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	%bp, %es
13976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
14076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	ADJUST_DRIVE
14176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	pushw	%dx			/* -14: dl -> drive number */
14276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
14376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Copy down to 0:0x600 */
14476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	$0x7c00, %si
14576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	$_start, %di
14676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	$(512/2), %cx
14776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	rep; movsw
14876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
14976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	ljmpw	$0, $next
15076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmannext:
15176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
15276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Check to see if we have EBIOS */
15376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	pushw	%dx		/* drive number */
15476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movb	$0x41, %ah	/* %al == 0 already */
15576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	$0x55aa, %bx
15676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	xorw	%cx, %cx
15776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	xorb	%dh, %dh
15876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	stc
15976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int	$0x13
16076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	jc	1f
16176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	cmpw	$0xaa55, %bx
16276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	jne	1f
16376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	andw	$1,%cx		/* Bit 0 = fixed disk subset */
16476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	jz	1f
16576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
16676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* We have EBIOS; patch in the following code at
16776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	   read_sector_cbios: movb $0x42, %ah ;  jmp read_common */
16876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movl	$0xeb42b4+((read_common-read_sector_cbios-4) << 24), \
16976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		(read_sector_cbios)
17076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	jmp	1f
17176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman1:
17276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	popw	%dx
17376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	pushw	%cx		/* EBIOS flag */
17476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
17576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Get (C)HS geometry */
17676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movb	$0x08, %ah
17776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int	$0x13
17876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	andw	$0x3f, %cx	/* Sector count */
17976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	popw	%bx		/* EBIOS flag */
18076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	pushw	%cx		/* -16: Save sectors on the stack */
18176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movzbw	%dh, %ax	/* dh = max head */
18276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	incw	%ax		/* From 0-based max to count */
18376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	pushw	%ax		/* -18: Save heads on the stack */
18476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	mulw	%cx		/* Heads*sectors -> sectors per cylinder */
18576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
18676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	pushw	%bx		/* -20: EBIOS flag */
18776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
18876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Save sectors/cylinder on the stack */
18976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	pushw	%dx		/* -22: High word */
19076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	pushw	%ax		/* -24: Low word */
19176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
19276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/*
19376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * Load sectors.  We do this one at a time mostly to avoid
19476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * pitfalls and to share code with the stock MBR code.
19576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 */
19676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	$0x7c00, %bx
19776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	$4, %cx		/* Sector count */
19876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movl	(lba_offset), %eax
19976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
20076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman2:
20176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	call	read_sector
20276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	jc	disk_error
20376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	incl	%eax
20476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	addb	$(512 >> 8), %bh
20576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	loopw	2b
20676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
20776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/*
20876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * Okay, that actually worked... update the stack pointer
20976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * and jump into isolinux.bin...
21076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 */
21176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	cmpl	$HYBRID_MAGIC,(isolinux_hybrid_signature)
21276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	jne	bad_signature
21376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
21476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	cli
21576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	$ebios_flag, %sp
21676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
21776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/*
21876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * Use a ljmpw here to work around a bug in some unknown version
21976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * of gas or ld when it comes to jumping to an absolute symbol...
22076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 *
22176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * Look more closely into it if we ever are short on space.
22276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 */
22376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	ljmpw	$0, $isolinux_start_hybrid
22476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
22576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanbad_signature:
22676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	call	error
22776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.ascii	"isolinux.bin missing or corrupt.\r\n"
22876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
22976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/*
23076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * read_sector: read a single sector pointed to by %eax to %es:%bx.
23176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * CF is set on error.  All registers saved.
23276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
23376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanread_sector:
23476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	pushal
23576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	xorl	%edx, %edx
23676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	addl	(partoffset), %eax
23776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	adcl	(partoffset+4), %edx
23876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	pushl	%edx	/* MSW of LBA */
23976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	pushl	%eax	/* LSW of LBA */
24076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	pushw	%es	/* Buffer segment */
24176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	pushw	%bx	/* Buffer offset */
24276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	pushw	$1	/* Sector count */
24376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	pushw	$16	/* Size of packet */
24476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	%sp, %si
24576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
24676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* This chunk is skipped if we have ebios */
24776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Do not clobber %eax before this chunk! */
24876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* This also relies on %bx and %edx as set up above. */
24976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanread_sector_cbios:
25076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	divl	(secpercyl)
25176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	shlb	$6, %ah
25276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movb	%ah, %cl
25376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movb	%al, %ch
25476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	xchgw	%dx, %ax
25576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	divb	(sectors)
25676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movb	%al, %dh
25776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	orb	%ah, %cl
25876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	incw	%cx	/* Sectors are 1-based */
25976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	$0x0201, %ax
26076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
26176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanread_common:
26276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movb	(driveno), %dl
26376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int	$0x13
26476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	leaw	16(%si), %sp	/* Drop DAPA */
26576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	popal
26676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	ret
26776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
26876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmandisk_error:
26976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	call	error
27076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.ascii	"Operating system load error.\r\n"
27176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
27276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/*
27376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Print error messages.  This is invoked with "call", with the
27476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * error message at the return address.
27576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
27676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanerror:
27776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	popw	%si
27876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman2:
27976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	lodsb
28076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movb	$0x0e, %ah
28176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movb	(BIOS_page), %bh
28276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movb	$0x07, %bl
28376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int	$0x10		/* May destroy %bp */
28476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	cmpb	$10, %al	/* Newline? */
28576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	jne	2b
28676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
28776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int	$0x18		/* Boot failure */
28876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmandie:
28976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	hlt
29076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	jmp	die
29176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
29276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Address of pointer to isolinux.bin */
29376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanlba_offset = _start+432
294