summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarty Connor2007-07-05 01:47:13 +0200
committerMarty Connor2007-07-05 01:47:13 +0200
commita75fb8010752dcf789d0ffb8a739023b9aff8365 (patch)
tree0db83ce1e078e5456f80440f1bef89c5289393ff
parentPurge warnings from prism2 drivers (diff)
parentAdded active partition locator, and simple MBR built using it. (diff)
downloadipxe-a75fb8010752dcf789d0ffb8a739023b9aff8365.tar.gz
ipxe-a75fb8010752dcf789d0ffb8a739023b9aff8365.tar.xz
ipxe-a75fb8010752dcf789d0ffb8a739023b9aff8365.zip
Merge branch 'master' of /pub/scm/gpxe
-rw-r--r--src/arch/i386/prefix/bootpart.S189
-rw-r--r--src/arch/i386/prefix/mbr.S13
2 files changed, 202 insertions, 0 deletions
diff --git a/src/arch/i386/prefix/bootpart.S b/src/arch/i386/prefix/bootpart.S
new file mode 100644
index 00000000..87104f59
--- /dev/null
+++ b/src/arch/i386/prefix/bootpart.S
@@ -0,0 +1,189 @@
+#define BOOT_SEG 0x07c0
+#define EXEC_SEG 0x0100
+#define STACK_SEG 0x0200
+#define STACK_SIZE 0x2000
+
+ .text
+ .arch i386
+ .section ".prefix", "awx", @progbits
+ .code16
+
+/*
+ * Find active partition
+ *
+ * Parameters:
+ * %dl : BIOS drive number
+ * %bp : Active partition handler routine
+ */
+find_active_partition:
+ /* Set up stack at STACK_SEG:STACK_SIZE */
+ movw $STACK_SEG, %ax
+ movw %ax, %ss
+ movw $STACK_SIZE, %sp
+ /* Relocate self to EXEC_SEG */
+ pushw $BOOT_SEG
+ popw %ds
+ pushw $EXEC_SEG
+ popw %es
+ xorw %si, %si
+ xorw %di, %di
+ movw $0x200, %cx
+ rep movsb
+ ljmp $EXEC_SEG, $1f
+1: pushw %ds
+ popw %es
+ pushw %cs
+ popw %ds
+ /* Read and process root partition table */
+ xorb %dh, %dh
+ movw $0x0001, %cx
+ xorl %esi, %esi
+ xorl %edi, %edi
+ call process_table
+ /* Print failure message */
+ movw $10f, %si
+ movw $(20f-10f), %cx
+1: movw $0x0007, %bx
+ movb $0x0e, %ah
+ lodsb
+ int $0x10
+ loop 1b
+ /* Boot next device */
+ int $0x18
+10: .ascii "Could not locate active partition\r\n"
+20:
+
+/*
+ * Process partition table
+ *
+ * Parameters:
+ * %dl : BIOS drive number
+ * %dh : Head
+ * %cl : Sector (bits 0-5), high two bits of cylinder (bits 6-7)
+ * %ch : Low eight bits of cylinder
+ * %esi:%edi : LBA address
+ * %bp : Active partition handler routine
+ *
+ * Returns:
+ * CF set on error
+ */
+process_table:
+ pushal
+ movw $446, %bx
+1: call read_sector
+ jc 99f
+ call process_partition
+ addw $16, %bx
+ cmpw $510, %bx
+ jne 1b
+99: popal
+ ret
+
+/*
+ * Process partition
+ *
+ * Parameters:
+ * %dl : BIOS drive number
+ * %dh : Head
+ * %cl : Sector (bits 0-5), high two bits of cylinder (bits 6-7)
+ * %ch : Low eight bits of cylinder
+ * %esi:%edi : LBA address
+ * %bx : Offset within partition table
+ * %bp : Active partition handler routine
+ */
+process_partition:
+ pushal
+ /* Load C/H/S values from partition entry */
+ movb %es:1(%bx), %dh
+ movw %es:2(%bx), %cx
+ /* Update LBA address from partition entry */
+ addl %es:8(%bx), %edi
+ adcl $0, %esi
+ /* Check active flag */
+ testb $0x80, %es:(%bx)
+ jz 1f
+ call read_sector
+ jc 99f
+ jmp *%bp
+1: /* Check for extended partition */
+ movb %es:4(%bx), %al
+ cmpb $0x05, %al
+ je 2f
+ cmpb $0x0f, %al
+ je 2f
+ cmpb $0x85, %al
+ jne 99f
+2: call process_table
+99: popal
+ ret
+
+/*
+ * Read single sector to 0000:7c00 and verify 0x55aa signature
+ *
+ * Parameters:
+ * %dl : BIOS drive number
+ * %dh : Head
+ * %cl : Sector (bits 0-5), high two bits of cylinder (bits 6-7)
+ * %ch : Low eight bits of cylinder
+ * %esi:%edi : LBA address
+ *
+ * Returns:
+ * CF set on error
+ */
+read_sector:
+ pushal
+ /* Check for LBA extensions */
+ call check_lba
+ jnc read_lba
+read_chs:
+ /* Read sector using C/H/S address */
+ movw $0x0201, %ax
+ xorw %bx, %bx
+ stc
+ int $0x13
+ sti
+ jmp 99f
+read_lba:
+ /* Read sector using LBA address */
+ movb $0x42, %ah
+ movl %esi, (lba_desc + 12)
+ movl %edi, (lba_desc + 8)
+ movw $lba_desc, %si
+ int $0x13
+99: /* Check for 55aa signature */
+ jc 99f
+ cmpw $0xaa55, %es:(510)
+ je 99f
+ stc
+99: popal
+ ret
+
+lba_desc:
+ .byte 0x10
+ .byte 0
+ .word 1
+ .word 0x0000
+ .word 0x07c0
+ .long 0, 0
+
+/*
+ * Check for LBA extensions
+ *
+ * Parameters:
+ * %dl : BIOS drive number
+ *
+ * Returns:
+ * CF clear if LBA extensions supported
+ */
+check_lba:
+ pushal
+ movb $0x41, %ah
+ movw $0x55aa, %bx
+ stc
+ int $0x13
+ jc 99f
+ cmpw $0xaa55, %bx
+ je 99f
+ stc
+99: popal
+ ret
diff --git a/src/arch/i386/prefix/mbr.S b/src/arch/i386/prefix/mbr.S
new file mode 100644
index 00000000..adfe2041
--- /dev/null
+++ b/src/arch/i386/prefix/mbr.S
@@ -0,0 +1,13 @@
+ .text
+ .arch i386
+ .section ".prefix", "awx", @progbits
+ .code16
+ .org 0
+
+mbr:
+ movw $exec_sector, %bp
+ jmp find_active_partition
+exec_sector:
+ ljmp $0x0000, $0x7c00
+
+#include "bootpart.S"