Creando un archivo IMG de disquete de arranque FreeDOS DOS para V86 en OSX

2

Estoy intentando crear un disco de arranque FreeDOS con OSX que sea compatible con la biblioteca V86 . Necesito hacer esto en la terminal (en un script de bash). Estoy haciendo todo esto en OSX High Sierra.

El disco de arranque que intento crear es un archivo .img de un disquete. Soy consciente de que hay otras formas de proporcionar discos de arranque a V86, como una imagen de disco duro o un cdrom .iso, pero estoy intentando de esta manera y me gustaría al menos entender qué estoy haciendo mal.

Sospecho que el problema que tengo es intentar crear correctamente el Registro de arranque maestro de la imagen del disquete (MBR) .

Para el contexto, aquí está mi comprensión del funcionamiento del proceso de arranque / MBR:

En los viejos tiempos en DOS o en máquinas Win9x, me parece recordar que tuve que ejecutar un comando de formato con algunos interruptores que haría que el MBR estuviera en el disco en lugar de solo una tabla FAT en la parte frontal del disco. aunque no estoy seguro si estoy entendiendo MBR correctamente.

Mi comprensión básica y simplificada del MBR es que el MBR son los primeros 512 bytes del disquete, que especifica qué tan grande es el disco, así como las instrucciones que le indican al BIOS que salte a la primera instrucción de un cargador de arranque que Voy a arrancar el sistema operativo. Por ejemplo, en un disquete de DOS hay / fue un fiel COMMAND.COM en él. Probablemente en ese caso, el MBR fue escrito para indicar a BIOS que comience la ejecución en la primera instrucción en COMMAND.COM.

Averiguar dónde está la primera instrucción parece que podría ser complicado porque es necesario que ocurran varias cosas (creo ...). Los primeros 512 bytes del disco se reservarán para el MBR, luego, después de eso, se escribe una FAT que toma otros X bytes del disco, luego, después de la FAT, hay espacio vacío para colocar los archivos. Cuando un archivo como COMMAND.COM se escribe en el disco, la FAT se actualiza con información sobre dónde se almacenan los bytes en el disco. Para que el MBR sepa dónde buscar la primera instrucción de COMMAND.COM, debe saber dónde está almacenado COMMAND.COM, que podría estar en cualquier lugar del disco en el espacio vacío después de la FAT, ¿verdad?

Aquí está mi intento actual de crear el disco:

# create a 720k empty img file with all zeros in it

dd if=/dev/zero of=myfloppy.img bs=1024 count=1440

# attach our .img file without mounting it, saving the attached name such as "/dev/disk2" in the var ${DEVICE}

DEVICE='hdiutil attach -nomount myfloppy.img'

# attempt to use diskutil to format the device as a bootable FAT12 diskette
# question: are dos boot diskettes supposed to be FAT12, FAT16, or FAT32?

diskutil eraseVolume "MS-DOS FAT12" MYFLOPPY bootable ${DEVICE}

# detach our unmounted .img file

hdiutil detach $DEVICE -force

# mount our source freedos image fetched from the V86 demo page, this mounts as /Volume/FREEDOS
# note that this sample image is also 720K

hdiutil mount freedos722.img 

# mount our target .img file we just created, it'll mount as /VOLUMES/MYFLOPPY

hdiutil mount myfloppy.img

# copy minimal set of files necessary to boot the disk (probably dont need autoexec.bat ..)
# question: does the copy order of these files matter? 

cp /Volumes/FREEDOS/COMMAND.COM /Volumes/MYFLOPPY/
cp /Volumes/FREEDOS/KERNEL.SYS /Volumes/MYFLOPPY/
cp /Volumes/FREEDOS/CONFIG.SYS /Volumes/MYFLOPPY/
cp /Volumes/FREEDOS/AUTOEXEC.BAT /Volumes/MYFLOPPY/

# unmount our disks

hdiutil unmount /Volumes/MYFLOPPY/
hdiutil unmount /Volumes/FREEDOS/

#TODO: might need to detach our image files even though we did mount/unmount above

La secuencia de comandos anterior me acerca al inicio, el inicio de V86 muestra "FREEDOS" en lugar de quejarse de que el disco no sea de inicio, pero se cuelga después de decir "FREEDOS", en lugar de continuar con el proceso de inicio.

También he intentado varias otras formas / intentos de crear el MBR, en todos estos casos creé el archivo img en blanco con el comando dd, luego lo ejecuté para crear el MBR, luego copié los archivos como se muestra arriba .

# Attempt #1: After the files are copied to the target disk, try to copy the 512 byte MBR from the source image to mine, if this worked I would be surprised, it didn't.
# this shouldn't work afaik because the MBR on the source image will have instructions to jump to the first instruction in COMMAND.COM as it's layed down on the source disk, which likely isn't where it is on our target disk.

dd if=freedos722.img of=myfloppy.img bs=512 count=1 conv=notrunc

# Attempt #2: try using the diskutil partition instead of erase disk command

diskutil partitiondisk ${DEVICE} 1 MBR "MS-DOS FAT12" "MYFLOPPY" 100%

# Attempt #3: try same as above, but with FAT16 (shouldn't work, didn't, because source img was FAT12)

diskutil partitiondisk ${DEVICE} 1 MBR "MS-DOS FAT16" "MYFLOPPY" 0B

# Attempt #4: use the newfs_msdos command without any diskutil commands

newfs_msdos -F 12 -v MYFLOPPY $DEVICE

# Attempt #5: use fdisk rather than any diskutil or newfs_msdos commands
# I *think* this is making an MBR, but not sure, maybe just making a partition
#note that I have no idea what to specify here for cylinders (c) and heads (h) and just copy/pasted this from somewhere

fdisk -i -c 1024 -h 255 -s 1440 -b 512 -a dos ${DEVICE}

# Attempt #6: use fdisk to create MBR / FAT, then use fdisk to mark that partition 'active'

fdisk -i -c 1024 -h 255 -s 1440 -b 512 -a dos ${DEVICE}
fdisk -e ${DEVICE} 
#fdisk -e puts us in an interactive edit mode, so we do the following
type 'a', then enter # gets us into 'set partition as active' mode
type '1', then enter # sets partition as active
type 'w', then enter # writes the MBR with the partition now marked active

También he intentado varios encantamientos donde mezclo los comandos anteriores, como ejecutar la partición diskutil y luego ejecutar el comando fdisk -i para ver si hay algo que fdisk haga para arreglar el MBR para la partición existente dada.

Soy consciente de que hay muchas formas de crear un disquete de arranque, pero quiero hacer esto en un script. Estos métodos se enumeran aquí por razones de integridad en caso de que otros estén buscando posibles formas de hacer esto:

1: use el instalador de FreeDOS en un entorno virtual como QEMU o VirtualBox, luego guarde una imagen del disquete creado.

2: use una máquina antigua para crear un disquete de arranque desde una instalación real de DOS o Windows.

Pensé que tal vez V86 tiene una posibilidad muy pequeña de arrancar un disquete si algo está mal, lo cual no tendría sentido ya que solo emula x86, pero también intenté arrancar desde varios intentos de creación con qemu. Para cualquier usuario que intente hacer eso, puede instalar qemu fácilmente con homebrew, luego arranque una máquina virtual simple con esto:

qemu-system-x86_64 -fda myfloppy.img

Y un enlace a un problema de V86 donde el desarrollador menciona cómo hacer imágenes QEMU a través de procesos de instalación completos del sistema operativo que funcionarán con V86:

enlace

Si no estás familiarizado con V86, es un emulador x86 escrito en la parte superior de asm.js que ejecuta un sistema operativo virtualizado en un navegador.

El autor tiene varios sistemas operativos de demostración de Linux, Windows y DOS que se ejecutan en v86 en su host personal:

enlace

Me tomó un poco descubrir cómo ejecutar solo su imagen de demostración de FreeDOS localmente sin la gran demostración que requiere la descarga de varias imágenes de SO, aquí está mi fuente para eso:

<!doctype html>
<script src="libv86.js"></script>
<script>
    "use strict";

    window.onload = function() {
            var emulator = window.emulator = new V86Starter({
            memory_size: 32 * 1024 * 1024,
            vga_memory_size: 2 * 1024 * 1024,
            screen_container: document.getElementById("screen_container"),
            bios: { url: "seabios.bin", },
            vga_bios: { url: "vgabios.bin", },
            fda: { "url": "freedos722-t.img", },
            autostart: true,
        });
    }
</script>

<div id="screen_container">
    <div style="white-space: pre; font: 14px monospace; line-height: 14px"></div>
    <canvas style="display: none"></canvas>
</div>

El archivo .img de FreeDOS que funciona con V86 se recuperó desde aquí:

enlace

    
pregunta Jason Baker 06.10.2018 - 05:19

1 respuesta

2

Aquí está mi intento actual de crear el disco:

# create a 720k empty img file with all zeros in it

dd if=/dev/zero of=myfloppy.img bs=512 count=1440

# after using the freedos722.img fetched from the V86 demo page 
# to determine the reserve was 1 logical sector, extract the boot code.

dd if=freedos722.img of=boot.img bs=512 count=1

# after using the 720K freedos722.img to determine the command 
# options, format the floppy image

newfs_msdos -B ./boot.img -v MYFLOPPY -f 720 -b 1024 -S 512 -r 1 -F 12 ./myfloppy.img

# remove the boot code file

rm boot.img

# mount our source freedos image fetched from the V86 demo page, 
# this mounts as /Volumes/FREEDOS

hdiutil attach -readonly freedos722.img 

# mount our target .img file we just created, it'll mount as /Volumes/MYFLOPPY

hdiutil attach myfloppy.img

# copy minimal set of files necessary to boot the disk (probably dont need autoexec.bat ..)
# note: the order of the files does not seem to matter.

cp /Volumes/FREEDOS/COMMAND.COM /Volumes/MYFLOPPY/
cp /Volumes/FREEDOS/KERNEL.SYS /Volumes/MYFLOPPY/
cp /Volumes/FREEDOS/CONFIG.SYS /Volumes/MYFLOPPY/
cp /Volumes/FREEDOS/AUTOEXEC.BAT /Volumes/MYFLOPPY/
mkdir /Volumes/MYFLOPPY/FDOS/
cp /Volumes/FREEDOS/FDOS/HIMEM.EXE /Volumes/MYFLOPPY/FDOS/

# eject our disks

hdiutil eject /Volumes/MYFLOPPY/
hdiutil eject /Volumes/FREEDOS/

Cómo determinar los valores enteros utilizados en los comandos anteriores

Para determinar el tamaño de la imagen del disquete y el tipo de FAT, ingrese la siguiente secuencia de comandos.

  1. El siguiente comando monta la imagen.

    hdiutil attach -readonly freedos722.img
    

    La salida de este comando se muestra a continuación. Esta salida muestra que el volumen se puede identificar como FREEDOS .

    /dev/disk1                                              /Volumes/FREEDOS
    
  2. Ingresa el siguiente comando para obtener información sobre la imagen.

    diskutil info FREEDOS
    

    A continuación se muestra el resultado pertinente de este comando.

       File System Personality:  MS-DOS FAT12
       Disk Size:                737.3 KB (737280 Bytes) (exactly 1440 512-Byte-Units)
    

    Entonces, aquí es donde se determinaron los valores de los parámetros bs=512 y count=1440 para crear el archivo de imagen vacío. Además, aquí es donde se determinó el valor del parámetro -F 12 para el comando newfs_msdos .

  3. Ingresa el siguiente comando para expulsar el volumen.

    diskutil eject FREEDOS
    

A continuación se muestra una tabla tomada de este sitio web de PCGuide . La fila "Sectores totales por disco" muestra la imagen para representar un disquete de 720 KB. Esto donde se determinó el valor del parámetro -f 720 para el comando newfs_msdos .

Algunosdelosdemásvaloresenterospuedentomarsedeestatabla.LosvalorestambiénsepuedenextraerdelBloquedeparámetrosdelBIOSalmacenadoenelarchivofreedos722.img.

ElcomandoacontinuaciónsepuedeusarparamostrarelRegistrodeiniciodevolumen(VBR)almacenadoenelarchivofreedos722.img.El Bloque de parámetros de la BIOS comienza en el desplazamiento 0x0B.

dd if=freedos722.img  count=1 bs=512 | hexdump -Cv

La estructura del Bloque de parámetros del BIOS se describe en la salida del comando man newfs_msdos . A continuación se muestra el resultado pertinente de este comando.

  

Nota: la salida a continuación muestra la asignación entre las opciones del comando newfs_msdos y los valores almacenados en el Bloque de parámetros del BIOS.

struct bsbpb {
    u_int16_t   bps;            /* [-S] bytes per sector */
    u_int8_t    spc;            /* [-c] sectors per cluster */
    u_int16_t   res;            /* [-r] reserved sectors */
    u_int8_t    nft;            /* [-n] number of FATs */
    u_int16_t   rde;            /* [-e] root directory entries */
    u_int16_t   sec;            /* [-s] total sectors */
    u_int8_t    mid;            /* [-m] media descriptor */
    u_int16_t   spf;            /* [-a] sectors per FAT */
    u_int16_t   spt;            /* [-u] sectors per track */
    u_int16_t   hds;            /* [-h] drive heads */
    u_int32_t   hid;            /* [-o] hidden sectors */
    u_int32_t   bsec;           /* [-s] big total sectors */
};
  

Nota: el parámetro [-s] big total sectors debe ignorarse. Utilice el parámetro [-s] total sectors en su lugar.

Una forma más elocuente de determinar los valores en el Bloque de parámetros del BIOS sería ingresar primero las definiciones de funciones que se detallan a continuación.

getint() { hexdump -s 0x$1 -n $2 -e \"%u\n\" freedos722.img; }
gethex() { hexdump -s 0x$1 -n $2 -e \"0x%x\n\" freedos722.img; }

Estas funciones tienen dos parámetros posicionales. El primero es el desplazamiento en el archivo freedos722.img . Este valor debe ser ingresado usando dígitos hexadecimales. El segundo es el número de bytes para leer. Los valores válidos son 1 , 2 y 4 .

La siguiente tabla muestra los comandos utilizados para extraer los siguientes valores del Bloque de parámetros del BIOS del archivo freedos722.img .

         Parameter               Command     Returned Value
----------------------------   -----------   --------------
[-S] bytes per sector          getint b  2         512
[-c] sectors per cluster       getint d  1           2
[-r] reserved sectors          getint e  2           1
[-n] number of FATs            getint 10 1           2 
[-e] root directory entries    getint 11 2         112
[-s] total sectors             getint 13 2        1440
[-m] media descriptor          gethex 15 1        0xf9
[-a] sectors per FAT           getint 16 2           3
[-u] sectors per track         getint 18 2           9
[-h] drive heads               getint 1a 2           2
[-o] hidden sectors            getint 1c 2           0
[-s] big total sectors         getint 1e 2           0

Los valores bytes per sector y reserved sectors se utilizaron para determinar los valores de los parámetros bs=512 y count=1 para el comando dd utilizado para crear el archivo de código de inicio boot.img . El valor del parámetro -b 1024 para el comando newfs_msdos se determinó multiplicando los valores bytes per sector y sectors per cluster juntos.

    
respondido por el David Anderson 06.10.2018 - 12:42

Lea otras preguntas en las etiquetas