[SeaBIOS] [PATCH v2] ramdisk: search for all available floppy images instead of one

Mike Banon posted 1 patch 5 years, 4 months ago
Failed in applying to current master (apply log)
[SeaBIOS] [PATCH v2] ramdisk: search for all available floppy images instead of one
Posted by Mike Banon 5 years, 4 months ago
Hi Kevin, thank you very much for the suggestions! This is a second
version of my "more_than_one_floppy" patch : now it will search for
the max size of floppy stored inside CBFS, then allocate this size of
RAM and use it later for any floppy selected by user. sha256 =
2f8bb18c1606d437de49e585769f100c085234de29d8520e2dc74d25b7f7645a
---
All the floppy images available at CBFS will be found and listed in a
boot menu, instead of the first found. Could be highly valuable if you
are participating in a hobby OS development - would like to test
multiple versions of your floppy in the same coreboot image, to reduce
the amount of re-flashes and accelerate the development at bare metal
- or simply would like to access multiple floppies as a coreboot user;
for example: KolibriOS (nice assembly OS with GUI), FreeDOS, Visopsys
and memtest (coreboot's own memtest version is a bit buggy, e.g.
external USB keyboard isn't working there at some laptops)

Shortened patch description message:

All the available floppy images will be found and listed in a boot
menu, instead of the first found. Useful if you are participating in a
hobby OS development or would like to access multiple floppies as a
coreboot user.

Signed-off-by: Mike Banon <mikebdp2 at gmail.com>
---
diff --git a/src/block.h b/src/block.h
index f64e880..aaa236f 100644
--- a/src/block.h
+++ b/src/block.h
@@ -2,7 +2,7 @@
 #define __BLOCK_H

 #include "types.h" // u32
-
+#include "romfile.h" // struct romfile_s

 /****************************************************************
  * Disk command request
@@ -48,6 +48,7 @@ struct drive_s {
 struct drive_s {
     u8 type;            // Driver type (DTYPE_*)
     u8 floppy_type;     // Type of floppy (only for floppy drives).
+    struct romfile_s *floppy_file; // Floppy file (only for virtual floppies).
     struct chs_s lchs;  // Logical CHS
     u64 sectors;        // Total sectors count
     u32 cntl_id;        // Unique id for a given driver type.
diff --git a/src/boot.c b/src/boot.c
index 9f82f3c..79f1e7d 100644
--- a/src/boot.c
+++ b/src/boot.c
@@ -584,7 +584,7 @@ bcv_prepboot(void)
             break;
         case IPL_TYPE_FLOPPY:
             map_floppy_drive(pos->drive);
-            add_bev(IPL_TYPE_FLOPPY, 0);
+            add_bev(IPL_TYPE_FLOPPY, (u32)pos->drive);
             break;
         case IPL_TYPE_HARDDISK:
             map_hd_drive(pos->drive);
@@ -733,6 +733,12 @@ do_boot(int seq_nr)
 static void
 do_boot(int seq_nr)
 {
+
+    int ret;
+    void *pos;
+    struct romfile_s *file;
+    struct drive_s *drive;
+
     if (! CONFIG_BOOT)
         panic("Boot support not compiled in.\n");

@@ -744,6 +750,16 @@ do_boot(int seq_nr)
     switch (ie->type) {
     case IPL_TYPE_FLOPPY:
         printf("Booting from Floppy...\n");
+        drive = (struct drive_s *)ie->vector;
+        file = drive->floppy_file;
+        // File is NULL if a floppy is physical.
+        if (file) {
+            // Copy virtual floppy image into ram.
+            pos = (void *)drive->cntl_id;
+            ret = file->copy(file, pos, file->size);
+            if (ret < 0)
+                break;
+        }
         boot_disk(0x00, CheckFloppySig);
         break;
     case IPL_TYPE_HARDDISK:
diff --git a/src/hw/floppy.c b/src/hw/floppy.c
index 9e6647d..5b37c6c 100644
--- a/src/hw/floppy.c
+++ b/src/hw/floppy.c
@@ -107,7 +107,7 @@ struct floppyinfo_s FloppyInfo[] VARFSEG = {
 };

 struct drive_s *
-init_floppy(int floppyid, int ftype)
+init_floppy(int floppyid, int ftype, struct romfile_s *ffile)
 {
     if (ftype <= 0 || ftype >= ARRAY_SIZE(FloppyInfo)) {
         dprintf(1, "Bad floppy type %d\n", ftype);
@@ -124,6 +124,7 @@ init_floppy(int floppyid, int ftype)
     drive->type = DTYPE_FLOPPY;
     drive->blksize = DISK_SECTOR_SIZE;
     drive->floppy_type = ftype;
+    drive->floppy_file = ffile;
     drive->sectors = (u64)-1;

     memcpy(&drive->lchs, &FloppyInfo[ftype].chs
@@ -134,7 +135,7 @@ addFloppy(int floppyid, int ftype)
 static void
 addFloppy(int floppyid, int ftype)
 {
-    struct drive_s *drive = init_floppy(floppyid, ftype);
+    struct drive_s *drive = init_floppy(floppyid, ftype, 0);
     if (!drive)
         return;
     char *desc = znprintf(MAXDESCSIZE, "Floppy [drive %c]", 'A' + floppyid);
diff --git a/src/hw/ramdisk.c b/src/hw/ramdisk.c
index b9e9baa..a679385 100644
--- a/src/hw/ramdisk.c
+++ b/src/hw/ramdisk.c
@@ -23,40 +23,69 @@ ramdisk_setup(void)
     if (!CONFIG_FLASH_FLOPPY)
         return;

-    // Find image.
-    struct romfile_s *file = romfile_findprefix("floppyimg/", NULL);
-    if (!file)
-        return;
-    const char *filename = file->name;
-    u32 size = file->size;
-    dprintf(3, "Found floppy file %s of size %d\n", filename, size);
-    int ftype = find_floppy_type(size);
-    if (ftype < 0) {
-        dprintf(3, "No floppy type found for ramdisk size\n");
+    struct romfile_s *file = NULL;
+    char *filename, *desc;
+    u32 size, max_size = 0;
+    int ftype;
+    void *pos;
+    struct drive_s *drive;
+
+    // Find the max floppy size
+    for (;;) {
+        // Find the next image.
+        file = romfile_findprefix("floppyimg/", file);
+        if (!file)
+            break;
+        filename = file->name;
+        size = file->size;
+        dprintf(3, "Found floppy file %s of size %d\n", filename, size);
+        // Check if this size is valid.
+        ftype = find_floppy_type(size);
+        if (ftype < 0) {
+            dprintf(3, "No floppy type found for ramdisk size\n");
+        } else {
+            if (size > max_size)
+                max_size = size;
+        }
+    }
+    if (max_size == 0) {
+        dprintf(3, "No floppies found\n");
         return;
     }

     // Allocate ram for image.
-    void *pos = memalign_tmphigh(PAGE_SIZE, size);
+    pos = memalign_tmphigh(PAGE_SIZE, max_size);
     if (!pos) {
         warn_noalloc();
         return;
     }
-    e820_add((u32)pos, size, E820_RESERVED);
+    e820_add((u32)pos, max_size, E820_RESERVED);
+    dprintf(3, "Allocate %u bytes for a floppy\n", max_size);

-    // Copy image into ram.
-    int ret = file->copy(file, pos, size);
-    if (ret < 0)
-        return;
-
-    // Setup driver.
-    struct drive_s *drive = init_floppy((u32)pos, ftype);
-    if (!drive)
-        return;
-    drive->type = DTYPE_RAMDISK;
-    dprintf(1, "Mapping floppy %s to addr %p\n", filename, pos);
-    char *desc = znprintf(MAXDESCSIZE, "Ramdisk [%s]", &filename[10]);
-    boot_add_floppy(drive, desc, bootprio_find_named_rom(filename, 0));
+    // Setup the floppy drivers.
+    file = NULL;
+    for (;;) {
+        // Find the next image.
+        file = romfile_findprefix("floppyimg/", file);
+        if (!file)
+            return;
+        filename = file->name;
+        size = file->size;
+        dprintf(3, "Found floppy file %s of size %d\n", filename, size);
+        ftype = find_floppy_type(size);
+        if (ftype < 0) {
+            dprintf(3, "No floppy type found for ramdisk size\n");
+        } else {
+            // Setup driver.
+            drive = init_floppy((u32)pos, ftype, file);
+            if (!drive)
+                return;
+            drive->type = DTYPE_RAMDISK;
+            dprintf(1, "Mapping floppy %s to addr %p\n", filename, pos);
+            desc = znprintf(MAXDESCSIZE, "Ramdisk [%s]", &filename[10]);
+            boot_add_floppy(drive, desc, bootprio_find_named_rom(filename, 0));
+        }
+    }
 }

 static int
diff --git a/src/util.h b/src/util.h
index 6dd080f..04f8018 100644
--- a/src/util.h
+++ b/src/util.h
@@ -147,7 +147,8 @@ void dma_setup(void);
 // hw/floppy.c
 extern struct floppy_ext_dbt_s diskette_param_table2;
 void floppy_setup(void);
-struct drive_s *init_floppy(int floppyid, int ftype);
+extern struct romfile_s *ffile;
+struct drive_s *init_floppy(int floppyid, int ftype, struct romfile_s *ffile);
 int find_floppy_type(u32 size);
 int floppy_process_op(struct disk_op_s *op);
 void floppy_tick(void);
_______________________________________________
SeaBIOS mailing list
SeaBIOS@seabios.org
https://mail.coreboot.org/mailman/listinfo/seabios
Re: [SeaBIOS] [PATCH v2] ramdisk: search for all available floppy images instead of one
Posted by Kevin O'Connor 5 years, 4 months ago
On Thu, Dec 06, 2018 at 07:12:19PM +0300, Mike Banon wrote:
> Hi Kevin, thank you very much for the suggestions! This is a second
> version of my "more_than_one_floppy" patch : now it will search for
> the max size of floppy stored inside CBFS, then allocate this size of
> RAM and use it later for any floppy selected by user. sha256 =
> 2f8bb18c1606d437de49e585769f100c085234de29d8520e2dc74d25b7f7645a

Thanks, see my comments below.

[...]
> ---
> diff --git a/src/block.h b/src/block.h
> index f64e880..aaa236f 100644
> --- a/src/block.h
> +++ b/src/block.h
> @@ -2,7 +2,7 @@
>  #define __BLOCK_H
> 
>  #include "types.h" // u32
> -
> +#include "romfile.h" // struct romfile_s
> 
>  /****************************************************************
>   * Disk command request
> @@ -48,6 +48,7 @@ struct drive_s {
>  struct drive_s {
>      u8 type;            // Driver type (DTYPE_*)
>      u8 floppy_type;     // Type of floppy (only for floppy drives).
> +    struct romfile_s *floppy_file; // Floppy file (only for virtual floppies).
>      struct chs_s lchs;  // Logical CHS
>      u64 sectors;        // Total sectors count
>      u32 cntl_id;        // Unique id for a given driver type.

Driver specific fields should not be added to drive_s - the code
should use the container_of() trick to allocate driver specific
fields.  (Create and allocate a custom driver struct that contains a
'struct drive_s' and when called with a drive_s use container_of() to
get a pointer back to that main struct - for an example, take a look
at what src/hw/usb-msc.c does.)

> diff --git a/src/boot.c b/src/boot.c
> index 9f82f3c..79f1e7d 100644
> --- a/src/boot.c
> +++ b/src/boot.c
> @@ -584,7 +584,7 @@ bcv_prepboot(void)
>              break;
>          case IPL_TYPE_FLOPPY:
>              map_floppy_drive(pos->drive);
> -            add_bev(IPL_TYPE_FLOPPY, 0);
> +            add_bev(IPL_TYPE_FLOPPY, (u32)pos->drive);
>              break;
>          case IPL_TYPE_HARDDISK:
>              map_hd_drive(pos->drive);
> @@ -733,6 +733,12 @@ do_boot(int seq_nr)
>  static void
>  do_boot(int seq_nr)
>  {
> +
> +    int ret;
> +    void *pos;
> +    struct romfile_s *file;
> +    struct drive_s *drive;
> +
>      if (! CONFIG_BOOT)
>          panic("Boot support not compiled in.\n");
> 
> @@ -744,6 +750,16 @@ do_boot(int seq_nr)
>      switch (ie->type) {
>      case IPL_TYPE_FLOPPY:
>          printf("Booting from Floppy...\n");
> +        drive = (struct drive_s *)ie->vector;
> +        file = drive->floppy_file;
> +        // File is NULL if a floppy is physical.
> +        if (file) {
> +            // Copy virtual floppy image into ram.
> +            pos = (void *)drive->cntl_id;
> +            ret = file->copy(file, pos, file->size);
> +            if (ret < 0)
> +                break;
> +        }

Similarly, we shouldn't add driver specific code into the boot phase.
A better place to do this would be during the BCV mapping phase (eg,
bcv_prepboot() ).  The idea is to do the work after the boot menu, but
before the boot phase.  Ideally the code would detect the driver wants
a callback and then call driver specific code that resides in
src/hw/ramdisk.c.

-Kevin

_______________________________________________
SeaBIOS mailing list
SeaBIOS@seabios.org
https://mail.coreboot.org/mailman/listinfo/seabios