[SeaBIOS] [PATCH 0/9] Misc boot related cleanups

Gleb Natapov gleb at redhat.com
Thu Dec 30 18:55:27 CET 2010


On Thu, Dec 30, 2010 at 12:20:17PM -0500, Kevin O'Connor wrote:
> On Thu, Dec 30, 2010 at 08:01:15AM +0200, Gleb Natapov wrote:
> > On Wed, Dec 29, 2010 at 08:23:13PM -0500, Kevin O'Connor wrote:
> > > Playing around with this a little further, I came up with the below.
> > > I'm not sure if it's better.
> > > 
> > For me it looks more complicated (may be because I am more familiar with
> > my own code ;))
> 
> The basic idea is to completely build the search string in the
> bootprio_find_X() function and then have it call find_prio() to return
> the priority.
> 
I understand the code, I just don't see why this is easier. Your code
also uses a lot of stack is this OK? It also assumes that device path is
no greater then 256 bytes long. With multiple bridges we can go over
this limit.

> >I see that you are starting to add regular expressions
> > engine!
> 
> Yes - I'm not happy about that.  Ultimately, rom loading needs some
> "fuzzy" matching capability, though.
> 
> > > I added a "magic" syntax to support rom instances (eg,
> > > /rom2 at genroms/linuxboot.bin, /pci at i0cf8/scsi at 3/rom2).  I also stubbed
> > > out some (admittedly wrong) pci bus path support.
> > > 
> > For supporting multiple pci buses we need to keep track of pci bus
> > topology in upper layers. Bus number in bdf is meaningless for device
> > path purposes.
> 
> Agreed.  I just need some way to make sure a bus2 device doesn't grab
> the priority of a bus0 request.
Ah yeah. This will do the trick.

> 
> > To boot from a certain file on a device OpenFirmware uses following
> > syntax: /path/to/device:filename i.e parameter goes after ':'.
> 
> Thanks.
> 
> > qemu -drive file=/dev/null,if=none,id=d1,media=cdrom -device ide-drive,drive=d1,bootindex=0 \
> 
> Thanks.
> 
> I've updated the patch - see below.
> 
> -Kevin
> 
> 
> diff --git a/src/boot.c b/src/boot.c
> index e83dcdc..b47f0fe 100644
> --- a/src/boot.c
> +++ b/src/boot.c
> @@ -13,6 +13,7 @@
>  #include "boot.h" // func defs
>  #include "cmos.h" // inb_cmos
>  #include "paravirt.h" // romfile_loadfile
> +#include "pci.h" //pci_bdf_to_*
>  
>  
>  /****************************************************************
> @@ -29,7 +30,7 @@ loadBootOrder(void)
>      if (!f)
>          return;
>  
> -    int i;
> +    int i = 0;
>      BootorderCount = 1;
>      while (f[i]) {
>          if (f[i] == '\n')
> @@ -48,38 +49,119 @@ loadBootOrder(void)
>      do {
>          Bootorder[i] = f;
>          f = strchr(f, '\n');
> -        if (f) {
> -            *f = '\0';
> -            f++;
> -            dprintf(3, "%d: %s\n", i, Bootorder[i]);
> -            i++;
> -        }
> +        if (f)
> +            *(f++) = '\0';
> +        dprintf(3, "%d: %s\n", i+1, Bootorder[i]);
> +        i++;
>      } while(f);
>  }
>  
> -int bootprio_find_pci_device(int bdf)
> +// See if 'str' matches 'glob' - if glob contains an '*' character it
> +// will match any number of characters in str that aren't a '/' or the
> +// next glob character.
> +static char *
> +glob_prefix(const char *glob, const char *str)
>  {
> +    for (;;) {
> +        if (!*glob && (!*str || *str == '/'))
> +            return (char*)str;
> +        if (*glob == *str) {
> +            glob++;
> +            str++;
> +            continue;
> +        }
> +        if (*glob != '*')
> +            return NULL;
> +        if (*str && *str != '/' && *str != glob[1])
> +            str++;
> +        else
> +            glob++;
> +    }
> +}
> +
> +// Search the bootorder list for the given glob pattern.
> +static int
> +find_prio(const char *glob)
> +{
> +    int i;
> +    for (i = 0; i < BootorderCount; i++)
> +        if (glob_prefix(glob, Bootorder[i]))
> +            return i+1;
>      return -1;
>  }
>  
> +#define FW_PCI_DOMAIN "/pci at i0cf8"
> +
> +static char *
> +build_pci_path(char *buf, int max, const char *devname, int bdf)
> +{
> +    // Build the string path of a bdf - for example: /pci at i0cf8/isa at 1,2
> +    char *p = buf;
> +    int bus = pci_bdf_to_bus(bdf);
> +    if (bus)
> +        // XXX - this isn't the correct path syntax
> +        p += snprintf(p, max, "/bus%x", bus);
> +
> +    int dev = pci_bdf_to_dev(bdf), fn = pci_bdf_to_fn(bdf);
> +    if (fn)
> +        snprintf(p, buf+max-p, "%s/%s@%x,%x", FW_PCI_DOMAIN, devname, dev, fn);
> +    else
> +        snprintf(p, buf+max-p, "%s/%s@%x", FW_PCI_DOMAIN, devname, dev);
> +    return buf;
> +}
> +
> +int bootprio_find_pci_device(int bdf)
> +{
> +    // Find pci device - for example: /pci at i0cf8/ethernet at 5
> +    char pci[256];
> +    return find_prio(build_pci_path(pci, sizeof(pci), "*", bdf));
> +}
> +
>  int bootprio_find_ata_device(int bdf, int chanid, int slave)
>  {
> -    return -1;
> +    if (bdf == -1)
> +        // support only pci machine for now
> +        return -1;
> +    // Find ata drive - for example: /pci at i0cf8/ide at 1,1/drive at 1/disk at 0
> +    char pci[256], desc[256];
> +    build_pci_path(pci, sizeof(pci), "*", bdf);
> +    snprintf(desc, sizeof(desc), "%s/drive@%x/disk@%x", pci, chanid, slave);
> +    return find_prio(desc);
>  }
>  
> -int bootprio_find_fdc_device(int bfd, int port, int fdid)
> +int bootprio_find_fdc_device(int bdf, int port, int fdid)
>  {
> -    return -1;
> +    if (bdf == -1)
> +        // support only pci machine for now
> +        return -1;
> +    // Find floppy - for example: /pci at i0cf8/isa at 1/fdc at 03f1/floppy at 0
> +    char pci[256], desc[256];
> +    build_pci_path(pci, sizeof(pci), "isa", bdf);
> +    snprintf(desc, sizeof(desc), "%s/fdc@%04x/floppy@%x", pci, port, fdid);
> +    return find_prio(desc);
>  }
>  
>  int bootprio_find_pci_rom(int bdf, int instance)
>  {
> -    return -1;
> +    // Find pci rom - for example: /pci at i0cf8/scsi at 3:rom2
> +    char pci[256], desc[256];
> +    build_pci_path(pci, sizeof(pci), "*", bdf);
> +    if (instance) {
> +        snprintf(desc, sizeof(desc), "%s:rom%d", pci, instance);
> +        return find_prio(desc);
> +    }
> +    return find_prio(pci);
>  }
>  
>  int bootprio_find_named_rom(const char *name, int instance)
>  {
> -    return -1;
> +    // Find named rom - for example: /rom at genroms/linuxboot.bin
> +    char desc[256];
> +    if (instance)
> +        snprintf(desc, sizeof(desc), "/rom@%s:rom%d", name, instance);
> +    else
> +        snprintf(desc, sizeof(desc), "/rom@%s", name);
> +    return find_prio(desc);
>  }
>  
>  
> @@ -167,6 +249,8 @@ bootentry_add(int type, int prio, u32 data, const char *desc)
>      be->priority = prio;
>      be->data = data;
>      be->description = desc ?: "?";
> +    dprintf(3, "Registering bootable: %s (type:%d prio:%d data:%x)\n"
> +            , be->description, type, prio, data);
>  
>      // Add entry in sorted order.
>      struct bootentry_s **pprev;

--
			Gleb.



More information about the SeaBIOS mailing list