Merge branch 'master' of rom.etherboot.org:/pub/scm/gpxe
authorMichael Brown <mcb30@etherboot.org>
Thu, 5 Jul 2007 13:15:58 +0000 (14:15 +0100)
committerMichael Brown <mcb30@etherboot.org>
Thu, 5 Jul 2007 13:15:58 +0000 (14:15 +0100)
src/arch/i386/Makefile
src/arch/i386/prefix/bootpart.S
src/arch/i386/prefix/hdprefix.S
src/arch/i386/prefix/usbdisk.S [new file with mode: 0644]

index ce147b7..f4e19d3 100644 (file)
@@ -98,6 +98,10 @@ MEDIA                        += com
 
 MEDIA                  += exe
 
+# Special target for building Master Boot Record binary
+$(BIN)/mbr.bin : $(BIN)/mbr.o
+       $(OBJCOPY) -O binary $< $@
+
 # Some suffixes (e.g. %.zfd0) are generated directly from other
 # finished files (e.g. %.zdsk), rather than having their own prefix.
 
@@ -117,6 +121,13 @@ NON_AUTO_MEDIA             += liso
 %liso: %lilo util/genliso
        bash util/genliso $@ $<
 
+# rule to make a USB disk image
+$(BIN)/usbdisk.bin : $(BIN)/usbdisk.o
+       $(OBJCOPY) -O binary $< $@
+
+%usb: $(BIN)/usbdisk.bin %hd
+       cat $^ > $@
+
 # Add NON_AUTO_MEDIA to the media list, so that they show up in the
 # output of "make"
 #
index 87104f5..d60fe9b 100644 (file)
@@ -20,6 +20,7 @@ find_active_partition:
        movw    $STACK_SEG, %ax
        movw    %ax, %ss
        movw    $STACK_SIZE, %sp
+
        /* Relocate self to EXEC_SEG */
        pushw   $BOOT_SEG
        popw    %ds
@@ -34,24 +35,46 @@ find_active_partition:
        popw    %es
        pushw   %cs
        popw    %ds
+
+       /* Check for LBA extensions */
+       movb    $0x41, %ah
+       movw    $0x55aa, %bx
+       stc
+       int     $0x13
+       jc      1f
+       cmpw    $0xaa55, %bx
+       jne     1f
+       movw    $read_lba, read_sectors
+1:     
        /* 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
+       jmp     boot_error
+10:    .asciz  "Could not locate active partition\r\n"
+
+/*
+ * Print failure message and boot next device
+ *
+ * Parameters:
+ *   %si       : Failure string
+ */
+boot_error:
+       cld
+       movw    $0x0007, %bx
        movb    $0x0e, %ah
-       lodsb
+1:     lodsb
+       testb   %al, %al
+       je      99f
        int     $0x10
-       loop    1b
-       /* Boot next device */
+       jmp     1b
+99:    /* Boot next device */
        int     $0x18
-10:    .ascii  "Could not locate active partition\r\n"
-20:    
 
 /*
  * Process partition table
@@ -69,10 +92,10 @@ find_active_partition:
  */
 process_table:
        pushal
-       movw    $446, %bx
-1:     call    read_sector
+       call    read_boot_sector
        jc      99f
-       call    process_partition
+       movw    $446, %bx
+1:     call    process_partition
        addw    $16, %bx
        cmpw    $510, %bx
        jne     1b
@@ -102,7 +125,7 @@ process_partition:
        /* Check active flag */
        testb   $0x80, %es:(%bx)
        jz      1f
-       call    read_sector
+       call    read_boot_sector
        jc      99f
        jmp     *%bp
 1:     /* Check for extended partition */
@@ -115,10 +138,12 @@ process_partition:
        jne     99f
 2:     call    process_table
 99:    popal
+       /* Reload original partition table */
+       call    read_boot_sector
        ret
 
 /*
- * Read single sector to 0000:7c00 and verify 0x55aa signature
+ * Read single sector to %es:0000 and verify 0x55aa signature
  *
  * Parameters:
  *   %dl       : BIOS drive number
@@ -130,32 +155,56 @@ process_partition:
  * Returns:
  *   CF set on error
  */
-read_sector:
-       pushal
-       /* Check for LBA extensions */
-       call    check_lba
-       jnc     read_lba
+read_boot_sector:
+       pushw   %ax
+       movw    $1, %ax
+       call    *read_sectors
+       jc      99f
+       cmpw    $0xaa55, %es:(510)
+       je      99f
+       stc     
+99:    popw    %ax
+       ret
+       
+/*
+ * Read sectors to %es:0000
+ *
+ * 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
+ *   %ax       : Number of sectors (max 127)
+ *
+ * Returns:
+ *   CF set on error
+ */
+read_sectors:  .word   read_chs
+
 read_chs:
-       /* Read sector using C/H/S address */
-       movw    $0x0201, %ax
+       /* Read sectors using C/H/S address */
+       pushal
        xorw    %bx, %bx
+       movb    $0x02, %ah
        stc
        int     $0x13
        sti
-       jmp     99f
+       popal
+       ret
+
 read_lba:
-       /* Read sector using LBA address */
-       movb    $0x42, %ah
-       movl    %esi, (lba_desc + 12)
+       /* Read sectors using LBA address */
+       pushal
+       movw    %ax, (lba_desc + 2)
+       pushw   %es
+       popw    (lba_desc + 6)
        movl    %edi, (lba_desc + 8)
+       movl    %esi, (lba_desc + 12)
        movw    $lba_desc, %si
+       movb    $0x42, %ah
        int     $0x13
-99:    /* Check for 55aa signature */
-       jc      99f
-       cmpw    $0xaa55, %es:(510)
-       je      99f
-       stc
-99:    popal
+       popal
        ret
 
 lba_desc:
@@ -163,27 +212,5 @@ lba_desc:
        .byte   0
        .word   1
        .word   0x0000
-       .word   0x07c0
+       .word   0x0000
        .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
index 2a6dc8e..ceab206 100644 (file)
-#warning "Needs fixing up for gpxe"
-
-#if 0
-
-/****************************************************************\
-
-hdprefix.S Copyright (C) 2005 Per Dalgas Jakobsen
-
-This code has been inspired/derived by the OSLoader by Vladislav Aleksandrov.
-http://www.programmersheaven.com/zone5/cat469/40546.htm.
-
-This software may be used and distributed according to the terms
-of the GNU Public License (GPL), incorporated herein by reference.
-
-hdprefix.S is loaded at 0x0000:0x7c00 by the bios-startup routines.
-
-Actions performed by hdprefix:
-1) Load the MBR to LOADSEG:0
-2) Check which partition is active (or try first partition if none active)
-3) Check wether LBA is supported.
-3a) LBA
-3a1) Load PAYLOAD_SECTS sectors from chosen partition to LOADSEG:0
-3b) CHS (standard)
-3b1) Load PAYLOAD_SECTS sectors from chosen partition to LOADSEG:0
-4) Check loaded bootsector for BOOTMAGIC code.
-5) Jump to payload LOADSEG:ENTRYPOINT.
-
-Output with failure points (!#):
----
-Loading (!1)partition #
-Std. BIOS(!2) | Ext. BIOS(!3)
-Booting...(!4)
-(!5)
----
-
-!1: Failed to load MBR with Int13,ah=2.
-!2: Failed to load bootrecord+payload with Int13,ah=2.
-!3: Failed to load bootrecord+payload with Int13,ah=42.
-!4: Invalid BOOTMAGIC in loaded bootrecord.
-!5: Jumping to payload.
-
-\*****************************************************************/
-.equ   BOOTSEG,        0x07c0
-.equ   LOADSEG,        0x1000
-.equ   ENTRYPOINT,     _start
-
-.equ   BOOTMAGIC,      0x0aa55
-
-.equ   partition_table,        0x1be
-.equ   partition_rec_size,     0x10
-
-.equ   boot_ind,       0       /* 80h=active */
-.equ   start_head,     1
-.equ   start_sector,   2       /* bits 0-5 */
-.equ   start_cyl,      3       /* bits 8,9 in bits 6,7 of sector */
-.equ   os_ind,         4       /* os indicator */
-.equ   end_head,       5
-.equ   end_sector,     6       /* bits 0-5 */
-.equ   end_track,      7       /* bits 8,9 in bits 6,7 of sector */
-.equ   nsect,          8       /* sectors preceding partition */
-.equ   lenght,         0x0c    /* length of partition in sectors */
-
-/-------------------------------------------------------------
-
-       .arch i386
        .text
-       .section ".prefix", "ax", @progbits
+       .arch i386
+       .section ".prefix", "awx", @progbits
        .code16
-        
-bootstart:
-       jmp     $BOOTSEG,$_go           /* reload cs:ip */
-
-
-/****************************************************************/
-/* support routines.                                           */
-/*--------------------------------------------------------------*/
-_failed:
-       movw    $BOOTSEG,%ax
-       movw    %ax,%ds
-       movw    $_failed_msg_end-_failed_msg,%cx
-       movw    $_failed_msg,%si
-       call    _print_str
-
-       /* stop execution - should probably have option to auto-reboot after delay. */
-_failed_loop:
-       jmp     _failed_loop
-
-/*--------------------------------------------------------------*/
-_print_str:
-       /* cx = count, ds:si = string. */
-       movw    $0x0007,%bx
-       movb    $0x0e,%ah
-_print_loop:
-       lodsb
-       int     $0x10
-       loop    _print_loop
-       ret
-
-/*--------------------------------------------------------------*/                     
-_print_char:
-       /* al = char. */
-       movw    $0x0007,%bx
-       movb    $0x0e,%ah
-       int     $0x10
-       ret
-
-/*--------------------------------------------------------------*/
-_print_nl:
-       /* - */
-       movb    $0x0d,%al
-       call    _print_char
-       movb    $0x0a,%al
-       call    _print_char
-       ret
-
-/*--------------------------------------------------------------*/
-_print_hex:
-       /* dx = value */
-       movb    $0x0e,%ah       /* write char, tty mode */
-       movw    $0x0007,%bx     /* page 0, attribute 7 (normal) */
-       call    _print_digit
-       call    _print_digit
-       call    _print_digit
-       /* fall through */
-_print_digit:
-       rolw    $4,%dx          /* rotate so that lowest 4 bits are used */
-       movb    $0x0f,%al       /* mask for nibble */
-       andb    %dl,%al
-       addb    $0x90,%al       /* convert al to ascii hex (four instructions) */
-       daa
-       adcb    $0x40,%al
-       daa
-       int     $0x10
-       ret
-
-/****************************************************************/
-
-
-_go:
-       cli
-       movw    $BOOTSEG,%ax
-       movw    %ax,%ds
-       movw    %ax,%ss
-       movw    $0x2000,%sp     /* good large stack. */
-       sti
-       cld
-       movw    $LOADSEG,%ax
-       movw    %ax,%es
+       .org 0
 
-       movw    $_load_msg_end-_load_msg,%cx
-       movw    $_load_msg,%si
-       call    _print_str
+       movw    $load_image, %bp
+       jmp     find_active_partition
 
-/*--- load MBR so we can use its partition table. ---*/
-       xorw    %bx,%bx
-       movw    $0x0001,%cx     /* chs: 0,0,1 */
-       movb    %bh,%dh         /* - */
-       movb    $0x80,%dl
-       movw    $0x0201,%ax     /* read one sector (MBR) */
-       int     $0x13
-       jc      _failed
-
-/*--- find the active partition ---*/
-       movw    $_part_msg_end-_part_msg,%cx
-       movw    $_part_msg,%si
-       call    _print_str
-
-       movw    $partition_table,%di
-       movw    $4,%cx
-_partition_loop:
-       cmpb    $0x80,%es:(%di)         /* active? */
-       je      _partition_found
-       addw    $partition_rec_size,%di
-       loop    _partition_loop
-
-       /*- no partitions marked active - use 1. partition. */
-       movw    $partition_table,%di
-       movw    $4,%cx
-
-_partition_found:
-       movb    $'5',%al                        /* convert to ascii */
-       subb    %cl,%al
-       call    _print_char
-       call    _print_nl
-
-/*--- check for lba support ---*/
-       movw    $0x55aa,%bx
-       movb    $0x80,%dl
-       movb    $0x41,%ah
-       int     $0x13
-       jc      __bios
-       cmpw    $0x0aa55,%bx
-       jnz     __bios
-       testb   $1,%cl
-       jz      __bios
+#include "bootpart.S"
 
-/*--- use lba bios calls to read sectors ---*/
-_lba:
-       movw    $_extbios_msg_end-_extbios_msg,%cx
-       movw    $_extbios_msg,%si
-       call    _print_str
-
-       movw    %es:nsect(%di),%ax
-       movw    %ax,_bios_lba_low
-       movw    %es:nsect+2(%di),%ax
-       movw    %ax,_bios_lba_high
-       movb    $0x80,%dl
-       movw    $_disk_address_packet,%si
-       movw    $0x4200,%ax     /* read */
-       int     $0x13
-       jc      _failed
-       jmp     __loaded
-
-/*--- use standard bios calls to read sectors ---*/
-__bios:
-       movw    $_stdbios_msg_end-_stdbios_msg,%cx
-       movw    $_stdbios_msg,%si
-       call    _print_str
-
-       movw    _disk_address_packet+2(,1),%ax  /* only low byte is used. */
-       xorw    %bx,%bx
-       movw    %es:start_sector(%di),%cx
-       movb    %es:start_head(%di),%dh
-       movb    $0x80,%dl
-       movb    $0x02,%ah
+load_image:
+       /* Get disk geometry */
+       pushal
+       pushw   %es
+       movb    $0x08, %ah
        int     $0x13
-       jc      _failed
-
-__loaded:
-       movw    $_boot_msg_end-_boot_msg,%cx
-       movw    $_boot_msg,%si
-       call    _print_str
-
-       /* check if it has a valid bootrecord. */
-       cmpw    $BOOTMAGIC,%es:510(,1)
-       jne     _failed
-       call    _print_nl
-
-       /* call the payload. */
-       pushl   $0              /* No parameters to preserve for exit path */
-       pushw   $0              /* Use prefix exit path mechanism */
-       jmp     $LOADSEG,$ENTRYPOINT
-
-       .section ".text16", "ax", @progbits
-       .globl  prefix_exit
-prefix_exit:
-       int     $0x19           /* should try to boot machine */
-       .globl  prefix_exit_end
-prefix_exit_end:
-       .previous
-        
-
-/*--------------------------------------------------------------*/
-
-_load_msg:     .ascii  "Loading "
-_load_msg_end:
-_part_msg:     .ascii  "partition "
-_part_msg_end:
-_boot_msg:     .ascii  "Booting..."
-_boot_msg_end:
-_stdbios_msg:  .ascii  "Std. BIOS\r\n"
-_stdbios_msg_end:
-_extbios_msg:  .ascii  "Ext. BIOS\r\n"
-_extbios_msg_end:
-_failed_msg:   .ascii  "FAILED!!!\r\n"
-_failed_msg_end:
-
-
-/*--------------------------------------------------------------*/
-
-_disk_address_packet:
-               .byte   0x10            /* size of the packet */
-               .byte   0               /* reserved */
-               .word   _verbatim_size_sct      /* number of sectors to read */
-               .word   0x0000          /* offset */
-               .word   LOADSEG         /* segment of buffer */
-_bios_lba_low: .word   0
-_bios_lba_high:        .word   0
-               .word   0
-               .word   0
-
-       .rept 32
-               .byte   0
-       .endr
-
-
-/*--- Partition table ------------------------------------------*/
-
-       .org 446, 0
-       .rept 64
-               .byte   0
-       .endr
-
-
-/*--- Magic code -----------------------------------------------*/
-       .org 510, 0
-               .word BOOTMAGIC
-
-/*** END ********************************************************/
-#endif
+       jc      load_failed
+       movb    %cl, max_sector
+       movb    %dh, max_head
+       popw    %es
+       popal
+       
+1:     /* Read to end of current track */
+       movb    %cl, %al
+       negb    %al
+       addb    max_sector, %al
+       incb    %al
+       andb    $0x3f, %al
+       movzbl  %al, %eax
+       call    *read_sectors
+       jc      load_failed
+       
+       /* Update %es */
+       movw    %es, %bx
+       shll    $5, %eax
+       addw    %ax, %bx
+       movw    %bx, %es
+       shrl    $5, %eax
+       
+       /* Update LBA address */
+       addl    %eax, %edi
+       adcl    $0, %esi
+       
+       /* Update CHS address */
+       andb    $0xc0, %cl
+       orb     $0x01, %cl
+       incb    %dh
+       cmpb    max_head, %dh
+       jbe     2f
+       xorb    %dh, %dh
+       incb    %ch
+       jnc     2f
+       addb    $0xc0, %cl
+2:
+       /* Loop until whole image is read */
+       subl    %eax, load_length
+       ja      1b
+       ljmp    $BOOT_SEG, $start_image
+
+load_length:
+       .long   _rom_size
+max_sector:
+       .byte   0
+max_head:
+       .byte   0
+
+load_failed:
+       movw    $10f, %si
+       jmp     boot_error
+10:    .asciz  "Could not load gPXE\r\n"
+
+       .org 510
+       .byte 0x55, 0xaa
+
+start_image:
+       call    install
+
+       /* Set up real-mode stack */
+       movw    %bx, %ss
+       movw    $_estack16, %sp
+
+       /* Jump to .text16 segment */
+       pushw   %ax
+       pushw   $1f
+       lret
+       .section ".text16", "awx", @progbits
+1:
+       pushl   $main
+       pushw   %cs
+       call    prot_call
+       popl    %eax /* discard */
+
+       /* Boot next device */
+       int $0x18
diff --git a/src/arch/i386/prefix/usbdisk.S b/src/arch/i386/prefix/usbdisk.S
new file mode 100644 (file)
index 0000000..07255d5
--- /dev/null
@@ -0,0 +1,23 @@
+       .text
+       .arch i386
+       .section ".prefix", "awx", @progbits
+       .code16
+       .org 0
+
+#include "mbr.S"
+
+/* Partition table: ZIP-compatible partition 4, 64 heads, 32 sectors/track */
+       .org 446
+       .space 16
+       .space 16
+       .space 16
+       .byte 0x80, 0x01, 0x01, 0x00
+       .byte 0x01, 0x3f, 0x20, 0x01
+       .long 0x00000020
+       .long 0x00000fe0
+
+       .org 510
+       .byte 0x55, 0xaa
+
+/* Skip to start of partition */
+       .org 32 * 512