diag/geodsp: Display Geometry based on read
authorGene Cumm <gene.cumm@gmail.com>
Thu, 10 Mar 2011 02:18:27 +0000 (21:18 -0500)
committerGene Cumm <gene.cumm@gmail.com>
Thu, 10 Mar 2011 02:18:27 +0000 (21:18 -0500)
This produces two images that are 8MiB+ in size (in order to exceed the
size of the largest CHS cylinder) containing 1 or multiple sectors of
code/data and the remaining sectors filled with their LBA.

diag/geodsp/Makefile [new file with mode: 0644]
diag/geodsp/README [new file with mode: 0644]
diag/geodsp/geodsp1s.asm [new file with mode: 0644]
diag/geodsp/geodsplib.inc [new file with mode: 0644]
diag/geodsp/geodspms.asm [new file with mode: 0644]
diag/geodsp/mk-lba-img.c [new file with mode: 0644]

diff --git a/diag/geodsp/Makefile b/diag/geodsp/Makefile
new file mode 100644 (file)
index 0000000..e2d710d
--- /dev/null
@@ -0,0 +1,63 @@
+## -----------------------------------------------------------------------
+##
+##   Copyright 2010-2011 Gene Cumm
+##
+##   Portions from core/Makefile:
+##   Copyright 1998-2009 H. Peter Anvin - All Rights Reserved
+##   Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin
+##
+##   This program is free software; you can redistribute it and/or modify
+##   it under the terms of the GNU General Public License as published by
+##   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
+##   Boston MA 02111-1307, USA; either version 2 of the License, or
+##   (at your option) any later version; incorporated herein by reference.
+##
+## -----------------------------------------------------------------------
+
+#
+# Makefile for the SYSLINUX geometry display for diagnostics
+#
+
+topdir = ../..
+# include $(topdir)/MCONFIG.embedded
+coredir = $(topdir)/core
+
+BTARGET = geodsp1s.bin geodspms.bin mk-lba-img \
+       geodsp1s.img.xz geodspms.img.xz
+#      lba-1s.img.xz lba-ms.img.xz
+  # lba-1s.img lba-ms.img
+
+NASMOPT = -i $(coredir)/ -Ox -f bin
+NASMOPT += -w+orphan-labels
+
+all: $(BTARGET)
+
+.PRECIOUS: %.img
+# .PRECIOUS: lba-%.img
+
+# Higher compression levels result in larger files
+%.img.xz: %.img
+       xz -k0f $<
+
+%.img.gz: %.img
+       gzip -9c $< > $@
+
+%.img: %.bin lba.img
+       (cp -a lba.img $@ && dd conv=notrunc if=$< of=$@) || rm -f $@
+
+%.bin: %.asm $(coredir)/writehex.inc $(coredir)/macros.inc $(coredir)/diskboot.inc
+       nasm $(NASMOPT) -o $@ -l $(@:.bin=.lst) $<
+
+mk-lba-img: mk-lba-img.c
+       gcc -o $@ $<
+
+lba.img: mk-lba-img
+       $< $@
+
+tidy dist:
+       rm -Rf *.img
+
+clean: tidy
+       rm -f $(BTARGET) *.lst *.bin *_bin.c
+
+spotless: clean
diff --git a/diag/geodsp/README b/diag/geodsp/README
new file mode 100644 (file)
index 0000000..43a3edc
--- /dev/null
@@ -0,0 +1,5 @@
+GeoDsp: Images to display the geometry as the BIOS has choosen to interpret it.  Both images are intended to be written to the first ~8MiB of a raw device (ie /dev/hda, /dev/sda) and be over one large cylinder of 255*63 512-byte sectors in size.
+
+GeoDsp1S is a one-sector variant containing all code in one sector that is intended to test behavior with a typical MBR/partition table layout.  A partition table should be written after writting an image.
+
+GeoDspMS is a multi sector variant intended to look like Syslinux installed on a file system on the raw device (as opposed to a file system within a partition).
diff --git a/diag/geodsp/geodsp1s.asm b/diag/geodsp/geodsp1s.asm
new file mode 100644 (file)
index 0000000..4ea84c4
--- /dev/null
@@ -0,0 +1,269 @@
+; -----------------------------------------------------------------------
+;
+;   Copyright 2010 Gene Cumm
+;
+;   Portions from diskstart.inc:
+;   Copyright 1994-2009 H. Peter Anvin - All Rights Reserved
+;   Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin
+;
+;   This program is free software; you can redistribute it and/or modify
+;   it under the terms of the GNU General Public License as published by
+;   the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+;   Boston MA 02110-1301, USA; either version 2 of the License, or
+;   (at your option) any later version; incorporated herein by reference.
+;
+; -----------------------------------------------------------------------
+
+;
+; geodsp1s.asm
+;
+; Display geometry translation info for diagnosing misconceptions
+; 1 sector variant
+;
+;      nasm -Ox -f bin -o geodsp.bin -l geodsp.lst geodsp.asm
+;
+;      nasm -Ox -f elf -o geodsp.o -l geodsp.lst geodsp.asm
+;      ld -m elf_i386  -T syslinux.ld -M -o geodsp.elf geodsp.o > geodsp.map
+;      objcopy -O binary geodsp.elf geodsp.raw
+;
+;      # OF=/dev/sdb
+;      # dd if=core/geodsp.bin of=$OF
+;      # dd skip=1 seek=1 if=../dbg/lba-img/lba-img.bin of=$OF
+;      # eject $OF
+;      # dd count=$() if=/dev/zero of=$OF
+;
+;      # OF=geo-2.255.63.i
+;      # (dd if=core/geodsp.bin; dd skip=1 if=../dbg/lba-img/lba-img.bin; dd count=$((2*255*63 - 256*63 - 1)) if=/dev/zero )|dd of=$OF
+;      # OF=geo-20.16.63.i
+;      # (dd if=core/geodsp.bin; dd skip=1 if=../dbg/lba-img/lba-img.bin; dd count=$((40*16*63 - 256*63 - 1)) if=/dev/zero )|dd of=$OF
+;
+
+%include "macros.inc"
+; %include "layout.inc"
+
+;              global STACK_LEN, STACK_TOP, STACK_BASE
+; STACK_LEN    equ 4096
+STACK_TOP      equ 7c00h
+; STACK_BASE   equ STACK_TOP - STACK_LEN
+
+StackBuf       equ STACK_TOP-44-92     ; Start the stack here (grow down - 4K)
+DriveNumber    equ StackBuf-4          ; Drive number
+m_CHS0         equ 00534843h           ;'CHS',0
+m_EDD0         equ 00444445h           ;'EDD',0
+m_EDD_SP       equ 20444445h           ;'EDD '
+retry_count    equ 16
+dbuf           equ 8000h
+int13_ret      equ 7e00h
+
+
+
+;              extern  real_mode_seg
+;              section .real_mode      write nobits align=65536
+;              global  core_real_mode
+; core_real_mode       resb 65536
+;              extern  xfer_buf_seg
+;              section .xfer_buf       write nobits align=65536
+;              global  core_xfer_buf
+; core_xfer_buf        resb 65536
+
+               section .text
+               org STACK_TOP
+
+
+               global _start
+bootsec                equ $
+_start:
+                       ; In case we want to pull more of the standard diskstart stuff in
+;              jmp short start         ; 2 bytes
+;              nop                     ; 1 byte
+start:
+               cli
+               cld
+               xor cx,cx
+               mov ss,cx
+               mov sp,StackBuf-2       ; Just below BSS (-2 for alignment)
+               push dx                 ; Save drive number (in DL)
+                       ; Kill everything else and let the BIOS sort it out later
+               mov es,cx
+               mov ds,cx
+               sti
+
+get_geo:               ; DL and ES ready
+               mov ah,08h
+               mov di,0
+               int 13h
+write_geo:
+               jc .bad_geo
+               mov si,s_chs
+               call writestr_early
+               call write_chs
+               call crlf
+               jmp short .done
+.bad_geo:
+.done:
+
+               mov bx,dbuf
+get_h1c:               ; 0,1,1
+               mov cx,0001h
+               mov dh,01h
+               call getonesec_chs
+               call write_chs_lba
+get_c1c:               ; 1,0,1
+               mov cx,0101h
+               mov dh,00h
+               call getonesec_chs
+               call write_chs_lba
+
+;
+; Do we have EBIOS (EDD)?
+;
+edd:
+.check:
+               mov bx,55AAh
+               mov ah,41h              ; EDD existence query
+               mov dl,[DriveNumber]
+               int 13h
+               jc .noedd
+               cmp bx,0AA55h
+               jne .noedd
+               test cl,1               ; Extended disk access functionality set
+               jz .noedd
+               ;
+               ; We have EDD support...
+               ;
+               mov bx,dbuf
+               xor edx,edx
+               mov dword [s_chs],m_EDD_SP
+.get_lba63:
+               mov eax,63      ; Same length as mov al,64; movzx eax,al
+               call getonesec_ebios
+               jc .bad_edd     ;read error
+               call write_edd_lba
+.get_lba16065:
+               mov eax,16065
+               call getonesec_ebios
+               jc .bad_edd     ;read error
+               call write_edd_lba
+.good_edd:
+               mov dword [s_type],m_EDD0
+.bad_edd:
+.noedd:
+.end:
+
+write_final_type:
+               mov si,s_typespec
+               call writestr_early
+
+               jmp short kaboom
+
+;
+; getonesec_ebios:
+;
+; getonesec implementation for EBIOS (EDD)
+;
+getonesec_ebios:
+               mov cx,retry_count
+.retry:
+               ; Form DAPA on stack
+               push edx
+               push eax
+               push es
+               push bx
+               push word 1
+               push word 16
+               mov si,sp
+               pushad
+                mov ah,42h                      ; Extended Read
+               call xint13
+               popad
+               lea sp,[si+16]                  ; Remove DAPA
+               jc .error
+                ret
+
+.error:
+               ; Some systems seem to get "stuck" in an error state when
+               ; using EBIOS.  Doesn't happen when using CBIOS, which is
+               ; good, since some other systems get timeout failures
+               ; waiting for the floppy disk to spin up.
+
+               pushad                          ; Try resetting the device
+               xor ax,ax
+               call xint13
+               popad
+               loop .retry                     ; CX-- and jump if not zero
+
+               ; Total failure.
+               stc
+               ret
+
+;
+; getonesec_chs:
+;
+; CX,DH specifies CHS address
+;
+getonesec_chs: ; We could use an xchg and get a loop
+;              mov cx,retry_count
+.retry:
+               pushad
+               mov ax,0201h            ; Read one sector
+               call xint13
+               popad
+               jc .error
+               ret
+
+.error:
+;              loop .retry
+               ; Fall through to disk_error
+;
+; kaboom: write a message and bail out.
+;
+               global kaboom
+disk_error:
+kaboom:
+.patch:
+               mov si,bailmsg
+               call writestr_early
+               xor eax,eax
+.again:                int 16h                 ; Wait for keypress
+                                       ; NB: replaced by int 18h if
+                                       ; chosen at install time..
+               int 19h                 ; And try once more to boot...
+.norge:                hlt                     ; If int 19h returned; this is the end
+               jmp short .norge
+
+;
+; INT 13h wrapper function
+;
+xint13:
+                mov dl,[DriveNumber]
+               int 13h
+               mov [int13_ret],ax
+               ret
+
+;
+;
+; writestr_early: write a null-terminated string to the console
+;          This assumes we're on page 0.  This is only used for early
+;           messages, so it should be OK.
+;
+writestr_early:
+               pushad
+.loop:         lodsb
+               and al,al
+                jz .return
+               call writechr
+               jmp short .loop
+.return:       popad
+               ret
+
+%include "geodsplib.inc"
+bailmsg                equ s_end
+
+               ; This fails if the boot sector overflowsg
+               zb 1BEh-($-$$)
+
+ptable         zb 40h          ; Partition table
+
+bootsignature  dw 0xAA55
+
+sector_2:
diff --git a/diag/geodsp/geodsplib.inc b/diag/geodsp/geodsplib.inc
new file mode 100644 (file)
index 0000000..5d6f705
--- /dev/null
@@ -0,0 +1,100 @@
+; -----------------------------------------------------------------------
+;
+;   Copyright 2010 Gene Cumm
+;
+;   Portions from diskstart.inc:
+;   Copyright 1994-2009 H. Peter Anvin - All Rights Reserved
+;   Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin
+;
+;   This program is free software; you can redistribute it and/or modify
+;   it under the terms of the GNU General Public License as published by
+;   the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+;   Boston MA 02110-1301, USA; either version 2 of the License, or
+;   (at your option) any later version; incorporated herein by reference.
+;
+; -----------------------------------------------------------------------
+
+;
+; geodsplib.inc
+;
+; Library file for geodsp*.asm
+;
+
+               ; ES:BX points to the buffer with address
+               ; DX,CX as they should be for INT13h,AH=02
+               ; For now assume C<256
+write_chs_lba:
+               pushad
+               mov si,s_atchs
+               call writestr_early
+               call write_chs
+               mov al,':'
+               call writechr
+               mov eax,[es:bx]
+               call writehex8
+               call crlf
+               popad
+               ret
+
+               ; DX,CX as they should be for INT13h,AH=02
+               ; For now assume C<256
+write_chs:
+               pushad
+               mov al,ch
+               mov ah,cl
+               shr ah,6
+               call writehex4
+               mov al,','
+               call writechr
+               mov al,dh
+               call writehex2
+               mov al,','
+               call writechr
+               mov al,cl
+               and al,3Fh
+               call writehex2
+               popad
+               ret
+
+write_edd_lba:
+               pushad
+               mov si,s_atchs
+               call writestr_early
+               call writehex8
+               mov al,':'
+               call writechr
+               mov eax,[es:bx]
+               call writehex8
+               call crlf
+               popad
+               ret
+
+
+crlf:
+               push si
+               mov si,s_crlf
+               call writestr_early
+               pop si
+               ret
+
+writechr:
+writechr_early:
+               pushad
+               mov ah,0Eh              ; Write to screen as TTY
+               mov bx,0007h            ; Attribute
+               int 10h
+               popad
+               ret
+
+%include "writehex.inc"
+
+s_atchs:       db '@'
+s_chs:         db 'CHS'
+s_space:       db ' ', 0
+s_typespec:    db 'D='
+s_type:                db 'CHS', 0
+s_end:         db 0Dh, 0Ah, 'end'
+s_crlf:                db 0Dh, 0Ah, 0
+
+; This indicates the general format of the last few bytes in the boot sector
+BS_MAGIC_VER   equ 0x1b << 9
diff --git a/diag/geodsp/geodspms.asm b/diag/geodsp/geodspms.asm
new file mode 100644 (file)
index 0000000..bd411eb
--- /dev/null
@@ -0,0 +1,196 @@
+; -----------------------------------------------------------------------
+;
+;   Copyright 2010 Gene Cumm
+;
+;   Portions from diskstart.inc:
+;   Copyright 1994-2009 H. Peter Anvin - All Rights Reserved
+;   Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin
+;
+;   This program is free software; you can redistribute it and/or modify
+;   it under the terms of the GNU General Public License as published by
+;   the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+;   Boston MA 02110-1301, USA; either version 2 of the License, or
+;   (at your option) any later version; incorporated herein by reference.
+;
+; -----------------------------------------------------------------------
+
+;
+; geodspms.asm
+;
+; Display geometry translation info for diagnosing misconceptions
+; multi-sector variant
+;
+;      nasm -Ox -f bin -o geodsp.bin -l geodsp.lst geodsp.asm
+;
+;      nasm -Ox -f elf -o geodsp.o -l geodsp.lst geodsp.asm
+;      ld -m elf_i386  -T syslinux.ld -M -o geodsp.elf geodsp.o > geodsp.map
+;      objcopy -O binary geodsp.elf geodsp.raw
+;
+;      # OF=/dev/sdb
+;      # dd if=core/geodsp.bin of=$OF
+;      # dd skip=1 seek=1 if=../dbg/lba-img/lba-img.bin of=$OF
+;      # eject $OF
+;      # dd count=$() if=/dev/zero of=$OF
+;
+;      # OF=geo-2.255.63.i
+;      # (dd if=core/geodsp.bin; dd skip=1 if=../dbg/lba-img/lba-img.bin; dd count=$((2*255*63 - 256*63 - 1)) if=/dev/zero )|dd of=$OF
+;      # OF=geo-20.16.63.i
+;      # (dd if=core/geodsp.bin; dd skip=1 if=../dbg/lba-img/lba-img.bin; dd count=$((40*16*63 - 256*63 - 1)) if=/dev/zero )|dd of=$OF
+;
+
+; Just to define it to look like SYSLINUX
+%define IS_SYSLINUX 1
+
+%include "macros.inc"
+; %include "layout.inc"
+
+m_CHS0         equ 00534843h           ;'CHS',0
+m_EDD0         equ 00444445h           ;'EDD',0
+m_EDD_SP       equ 20444445h           ;'EDD '
+retry_count    equ 16
+dbuf           equ 8000h
+; int13_ret    equ 7e00h
+LDLINUX_MAGIC  equ 0x3eb202fe          ; A random number to identify ourselves with
+
+Sect1Ptr0_VAL  equ 1
+Sect1Ptr1_VAL  equ 0
+
+;              global STACK_LEN, STACK_TOP, STACK_BASE
+; STACK_LEN    equ 4096
+STACK_TOP      equ 7c00h
+; STACK_BASE   equ STACK_TOP - STACK_LEN
+               section .init
+               org STACK_TOP
+geodsp_start:
+
+%include "diskboot.inc"
+
+HEXDATE                equ 1
+
+               section .init
+sector_1:
+ldlinux_sys:
+               alignz 8
+ldlinux_magic  dd LDLINUX_MAGIC
+               dd LDLINUX_MAGIC^HEXDATE
+
+
+ldlinux_ent:
+
+get_geo:               ; DL and ES ready
+               mov ah,08h
+               mov di,0
+               call xint13
+write_geo:
+               jc .bad_geo
+               mov si,s_chs
+               call writestr_early
+               call write_chs
+               call crlf
+               jmp short .done
+.bad_geo:
+.done:
+
+               mov bx,dbuf
+get_h1c:               ; 0,1,1
+               mov cx,0001h
+               mov dh,01h
+               call getonesec_chs
+               call write_chs_lba
+get_c1c:               ; 1,0,1
+               mov cx,0101h
+               mov dh,00h
+               call getonesec_chs
+               call write_chs_lba
+
+
+
+; Do we have EBIOS (EDD)?
+;
+edd:
+.check:
+               mov bx,55AAh
+               mov ah,41h              ; EDD existence query
+               call xint13
+               jc .noedd
+               cmp bx,0AA55h
+               jne .noedd
+               test cl,1               ; Extended disk access functionality set
+               jz .noedd
+               ;
+               ; We have EDD support...
+               ;
+               mov bx,dbuf     ; ES should still be safe.
+               xor edx,edx
+               mov dword [s_chs],m_EDD_SP
+.get_lba63:
+               mov eax,63      ; Same length as mov al,64; movzx eax,al
+               call getonesec_ebios
+               jc .bad_edd     ;read error
+               call write_edd_lba
+.get_lba16065:
+               mov eax,16065
+               call getonesec_ebios
+               jc .bad_edd     ;read error
+               call write_edd_lba
+.good_edd:
+               mov dword [s_type],m_EDD0
+.bad_edd:
+.noedd:
+.end:
+
+write_final_type:
+               mov si,s_typespec
+               call writestr_early
+               jmp kaboom
+
+;
+; getonesec_chs:
+;
+; CX,DH specifies CHS address
+;
+getonesec_chs: ; We could use an xchg and get a loop
+;              mov cx,retry_count
+.retry:
+               pushad
+               mov ax,0201h            ; Read one sector
+               call xint13
+               popad
+               jc .error
+               ret
+
+.error:
+;              loop .retry
+               ; Fall through to disk_error
+               jmp disk_error
+
+%include "geodsplib.inc"
+
+;
+;
+; writestr_early: write a null-terminated string to the console
+;          This assumes we're on page 0.  This is only used for early
+;           messages, so it should be OK.
+;
+writestr_early:
+               pushad
+.loop:         lodsb
+               and al,al
+                jz .return
+               mov ah,0Eh              ; Write to screen as TTY
+               mov bx,0007h            ; Attribute
+               int 10h
+               jmp short .loop
+.return:       popad
+               ret
+
+SuperInfo:     zd 32                   ; The first 16 bytes expanded 8 times
+
+               ; This fails if the sector overflowsg
+               zb 400h-($-$$)
+end:
+
+               absolute 4*1Eh
+fdctab         equ $
+fdctab1                resw 1
+fdctab2                resw 1
diff --git a/diag/geodsp/mk-lba-img.c b/diag/geodsp/mk-lba-img.c
new file mode 100644 (file)
index 0000000..795de1a
--- /dev/null
@@ -0,0 +1,75 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2010 Gene Cumm
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
+ *   Boston MA 02111-1307, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * mk-lba-img.c
+ *
+ * Makes an image that contains the LBA in every *word of every sector
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+
+#define NUM_SECT (256*63+1)
+#define BPS (512)
+#define SECT_INT (512 / sizeof(int))
+
+typedef unsigned char uint8_t;
+typedef unsigned int uint32_t;
+
+const char DEF_FN[] = "lba.img";
+
+int main(int argc, char *argv[])
+{
+       int i, j, b[SECT_INT], rv = 0, one = 0;
+       FILE *f;
+       uint8_t tt = 0;
+       const char *fn;
+
+       if (argc >= 2) {
+               if (argc >= 3) {
+                       if (strcasecmp("-1", argv[1]) == 0) {
+                               fn = argv[2];
+                               one = 1;
+                       } else {
+                               fn = argv[1];
+                       }
+               } else {
+                       fn = argv[1];
+               }
+       } else {
+               fn = DEF_FN;
+       }
+
+       f = fopen(fn, "w");
+
+       if (f) {
+               for (i = 0; i < NUM_SECT; i++) {
+                       if (one) {
+                               b[0] = i;
+                       } else {
+                               for (j = 0; j < (512 / sizeof(int)); j++) {
+                                       b[j] = i;
+                               }
+                       }
+                       fwrite(b, 512, 1, f);
+               }
+               fclose(f);
+       } else {
+               puts("Unable to open for writing");
+               rv = 1;
+       }
+       return rv;
+}