Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/i386/stand/fatboot Add support for directly booting...



details:   https://anonhg.NetBSD.org/src/rev/331c87b12e90
branches:  trunk
changeset: 777953:331c87b12e90
user:      dsl <dsl%NetBSD.org@localhost>
date:      Sat Mar 10 23:59:36 2012 +0000

description:
Add support for directly booting from FAT12 filesystems.
This shouldn't really be needed except that Linux wont
mount a small FAT16 filesystem - it always treats it as FAT12
even when you tell it otherwise.
There was enough free space before the main FS on the USB stick
I've been using for an extra small FAT fs to boot from.

diffstat:

 sys/arch/i386/stand/fatboot/Makefile       |   5 +-
 sys/arch/i386/stand/fatboot/fat12/Makefile |   6 +++
 sys/arch/i386/stand/fatboot/fatboot.S      |  57 +++++++++++++++++++++++------
 3 files changed, 54 insertions(+), 14 deletions(-)

diffs (177 lines):

diff -r 655c317abdc5 -r 331c87b12e90 sys/arch/i386/stand/fatboot/Makefile
--- a/sys/arch/i386/stand/fatboot/Makefile      Sat Mar 10 23:01:07 2012 +0000
+++ b/sys/arch/i386/stand/fatboot/Makefile      Sat Mar 10 23:59:36 2012 +0000
@@ -1,6 +1,7 @@
-# $NetBSD: Makefile,v 1.2 2007/01/06 20:47:15 dsl Exp $
+# $NetBSD: Makefile,v 1.3 2012/03/10 23:59:36 dsl Exp $
 
-SUBDIR=        fat16
+SUBDIR=                fat16
+SUBDIR+=       fat12
 
 .include <bsd.subdir.mk>
 .include <bsd.obj.mk>
diff -r 655c317abdc5 -r 331c87b12e90 sys/arch/i386/stand/fatboot/fat12/Makefile
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/i386/stand/fatboot/fat12/Makefile        Sat Mar 10 23:59:36 2012 +0000
@@ -0,0 +1,6 @@
+# $NetBSD: Makefile,v 1.1 2012/03/10 23:59:36 dsl Exp $
+
+PROG=bootxx_fat12
+FAT_ENTRY_SIZE=12
+
+.include <../Makefile.fat>
diff -r 655c317abdc5 -r 331c87b12e90 sys/arch/i386/stand/fatboot/fatboot.S
--- a/sys/arch/i386/stand/fatboot/fatboot.S     Sat Mar 10 23:01:07 2012 +0000
+++ b/sys/arch/i386/stand/fatboot/fatboot.S     Sat Mar 10 23:59:36 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: fatboot.S,v 1.3 2008/04/29 06:53:02 martin Exp $       */
+/*     $NetBSD: fatboot.S,v 1.4 2012/03/10 23:59:36 dsl Exp $  */
 
 /*-
  * Copyright (c) 2007 The NetBSD Foundation, Inc.
@@ -50,10 +50,12 @@
 #endif
 
 /* Support for FAT32 could be added - but hasn't been yet. */
-#if FAT_ENTRY_SIZE != 16
+#if FAT_ENTRY_SIZE != 16 && FAT_ENTRY_SIZE != 12
 #error Unsupported FAT_ENTRY_SIZE value
 #endif
 
+#define FAT_SIZE_STR (('0'+ FAT_ENTRY_SIZE / 10) | ('0' + FAT_ENTRY_SIZE % 10) << 8)
+
 #define PBR_AFTERBPB   62              /* BPB size in floppy master BR */
 
 #ifdef TERSE_ERROR
@@ -112,8 +114,13 @@
        mov     %sp, %bp                /* to access the pbp */
        push    %dx                     /* save drive at -2(%bp) */
 
+/* We put the LBA bios command block on stack.
+ * Since we only want a 32bit sector number, stack a zero */
+       push    %cs                     /* %cs is zero */
+       push    %cs                     /* 64-bit for LBA read */
+
        set_err(ERR_NOT_FAT16)
-       cmpl    $'A'|'T'<<8|'1'<<16|'6'<<24, bs_file_sys_type+1(%bp)
+       cmpl    $'A'|'T'<<8|FAT_SIZE_STR<<16, bs_file_sys_type+1(%bp)
        jne     error
 
 /* Add 'reserved' (inside ptn) to 'hidden' (ptn offset) */
@@ -121,14 +128,21 @@
        addl    bpb_hidden_secs(%bp), %eax
        mov     %eax, fat_sector(%bp)   /* To get first sector of FAT */
 
+#if FAT_ENTRY_SIZE == 12
+/* Read the entire FAT */
+       push    %eax
+       push    %ds
+       push    $fat_buffer
+       push    $12                     /* 12 sectors is assumed 6k */
+       call    read_lba
+#endif
+
 /* Determine base of root directory */
        movzbw  bpb_FATs(%bp), %ax      /* Count of FATs */
        mulw    bpb_FAT_secs(%bp)       /* FAT size in %dx:%ax */
        shl     $16,%edx
        xchg    %ax,%dx                 /* FAT size now in %edx */
        addl    fat_sector(%bp), %edx   /* Directory is after FATs */
-       push    %cs                     /* %cs is zero */
-       push    %cs                     /* 64-bit for LBA read */
        pushl   %edx                    /* Sector number of root dir */
 
        push    $0x1000                 /* Read to 0x10000:0 */
@@ -149,7 +163,7 @@
 /* Read in the entire root directory */
        push    %ax                     /* Sectors in root directory */
        cwtl
-       addl    %eax, %edx              /* %edx now sector of first file */
+       addl    %eax, %edx              /* %edx now sector of first cluster */
        call    read_lba                /* Read entire directory */
 
 /* Scan directory for our file */
@@ -195,16 +209,16 @@
        jnz     1b
        dec %cx
        dec %cx
-       movw    %es:15(%di), %ax        /* Cluster number for file start */
+       movw    %es:(26-11)(%di), %ax   /* Cluster number for file start */
        push    %es                     /* We increment the 'segment' ... */
        pop     %di                     /* ... after each read, offset is 0 */
 
 read_data_block:
        mov     %ax, %bx                /* Save cluster number */
        shl     %cl, %eax               /* Convert to sector number */
-       add     %eax, %edx
-       pushl   %edx                    /* Sector to read */
-       sub     %eax, %edx              /* Recover base segment */
+       jz      error                   /* Sanity bail-out */
+       add     %edx, %eax
+       pushl   %eax                    /* Sector to read */
        push    %di                     /* Target address segment! */
        push    $0
        push    sec_p_cl_w(%bp)
@@ -218,6 +232,20 @@
 
 /* Lookup FAT slot number in FAT table */
        mov     %bx, %ax                /* Recover cluster number */
+#if FAT_ENTRY_SIZE == 12
+       shr     $1, %ax
+       jc      1f
+       add     %ax, %bx
+       mov     fat_buffer(%bx), %ax
+       and     $0xf,%ah
+       jmp     2f
+1:     add     %ax, %bx
+       mov     fat_buffer(%bx), %ax
+       shr     $4, %ax
+2:
+       cmp     $0x0fff, %ax
+       jb      read_data_block
+#else
        push    %dx
        xor     %dx, %dx
        divw    bpb_bytes_per_sec(%bp)
@@ -243,6 +271,7 @@
        movzwl  fat_buffer(%bx), %eax   /* Next FAT slot */
        cmp     $0xfff0, %ax
        jb      read_data_block
+#endif
 
 /* Found end of FAT chain - must be EOF  - leap into loaded code */
        mov     $0x1000, %ax
@@ -255,7 +284,7 @@
 /* Set parameters expected by /boot */
 magic_ok:
        mov     bpb_hidden_secs(%bp), %ebx      /* ptn base sector */
-       movb    -2(%bp), %dl            /* disk number (could pop %dx) */
+       movb    -2(%bp), %dl            /* disk number */
        mov     $boot_params + 4, %si
        push    %es
        push    $0
@@ -286,6 +315,7 @@
 #include <message.S>
 #if 0
 #include <dump_eax.S>
+dump_eax_buff = start
 #endif
 
 errtxt: .ascii "Error "                /* runs into newline... */
@@ -296,7 +326,9 @@
 #ifndef TERSE_ERROR
 ERR_READ:              .asciz  "Disk read"
 ERR_NO_BOOT:           .asciz  "No /boot"
-ERR_NOT_FAT16:         .asciz  "Not FAT16 ptn"
+ERR_NOT_FAT16:         .ascii  "Not FAT"
+                       .word   FAT_SIZE_STR
+                       .asciz  " ptn"
 ERR_NO_BOOT_MAGIC_2:   .asciz  "No magic in /boot"
 #endif
 
@@ -321,3 +353,4 @@
        . = _C_LABEL(start) + 0x1fe
        .word   0xaa55
 fat_buffer:                            /* 2 sectors worth of FAT table */
+                                       /* 6k for FAT12 */



Home | Main Index | Thread Index | Old Index