Trimming CC list, adding seabios list.
On Sat, Nov 27, 2010 at 09:04:24PM +0200, Gleb Natapov wrote:
On Sat, Nov 27, 2010 at 01:40:12PM -0500, Kevin O'Connor wrote:
On Sat, Nov 27, 2010 at 08:15:42PM +0200, Gleb Natapov wrote:
Qemu does not know that Seabios needs optionrom to boot from a device. It knows even less about bcvs in option rom. Qemu knows about device itself, not how firmware boots from it.
If the user wants to boot from a device and that device has an optionrom, then it's a safe bet that the optionrom is needed to boot from it.
Suppose we add SCSI support to Seabios and suppose SCSI card Seabios can natively boot from has optionrom. What Seabios will do in such situation and how qemu can know it? Besides qemu support tries to be firmware agnostic.
In such a situation, under my proposal, users wouldn't be able to specify a default boot from their scsi drive until after qemu was also upgraded to know seabios could boot native scsi. (Or, they'd only be able to do it by adding in a command-line option.)
In any case, I'd rather have qemu know which devices seabios can boot then have seabios try to figure out what rom to run from a device path.
You run all of them just like you do now. Information you get from qemu is only used for sorting BCV/BEV entries. BCV/BEV that does not have corespondent boot path in boot order list is put at the end.
If qemu sends in "/pci@i0cf8/scsi@3/disk@0,0" or "/pci@i0cf8/ethernet@4/ethernet-phy@0" it will expect seabios to boot from the appropriate device. In both cases, seabios would need to run a rom in order to fulfill that request. Trying to figure out which rom is quite painful. That's why I'd prefer to see qemu instead pass in something like "/pci@i0cf8/rom@3/bcv@0" or "/pci@i0cf8/rom@4/bev". That is, if the machine needs to boot via a rom I'd prefer qemu state that explicitly.
BTW, in the situation where seabios has native device support (eg, ATA), I don't have any concerns. (The names are a bit verbose, but that's not really an issue.)
BTW are you actually aware of any option rom with multiple BCVs and, if yes, how those BCVs differ?
Multiple BCVs - yes. A SCSI card will define a BCV for each attached drive. I don't have a scsi card myself, but the support was added by a user who ran into the problem first hand.
Optionrom is static. How number of BCVs can depend on number of attached drives?
Not sure what you mean by "Optionrom is static". SeaBIOS unlocks the memory, and the optionrom can and will modify itself with additional PNP headers so that it can list multiple BCVs - one for each drive. In particular, gPXE uses self modification to relocate parts of itself into high ram.
-Kevin
On Sat, Nov 27, 2010 at 04:07:45PM -0500, Kevin O'Connor wrote:
Trimming CC list, adding seabios list.
On Sat, Nov 27, 2010 at 09:04:24PM +0200, Gleb Natapov wrote:
On Sat, Nov 27, 2010 at 01:40:12PM -0500, Kevin O'Connor wrote:
On Sat, Nov 27, 2010 at 08:15:42PM +0200, Gleb Natapov wrote:
Qemu does not know that Seabios needs optionrom to boot from a device. It knows even less about bcvs in option rom. Qemu knows about device itself, not how firmware boots from it.
If the user wants to boot from a device and that device has an optionrom, then it's a safe bet that the optionrom is needed to boot from it.
Suppose we add SCSI support to Seabios and suppose SCSI card Seabios can natively boot from has optionrom. What Seabios will do in such situation and how qemu can know it? Besides qemu support tries to be firmware agnostic.
In such a situation, under my proposal, users wouldn't be able to specify a default boot from their scsi drive until after qemu was also upgraded to know seabios could boot native scsi. (Or, they'd only be able to do it by adding in a command-line option.)
If scsi card has optionrom with only one bcv then Seabios can determine its boot order from device path, so why not provide user with this option today? Besides qemu may be used to emulates sparc with openbios and this combination may be able to boot from scsi device. Qemu is not just x86 emulator running Seabios. If there is problem with scsi boot we let management know, so it will not create unbootable configuration. Today it is impossible to boot guest from scsi in qemu btw.
In any case, I'd rather have qemu know which devices seabios can boot then have seabios try to figure out what rom to run from a device path.
You run all of them just like you do now. Information you get from qemu is only used for sorting BCV/BEV entries. BCV/BEV that does not have corespondent boot path in boot order list is put at the end.
If qemu sends in "/pci@i0cf8/scsi@3/disk@0,0" or "/pci@i0cf8/ethernet@4/ethernet-phy@0" it will expect seabios to boot from the appropriate device. In both cases, seabios would need to run a rom in order to fulfill that request. Trying to figure out which rom is quite painful. That's why I'd prefer to see qemu instead pass in something like "/pci@i0cf8/rom@3/bcv@0" or "/pci@i0cf8/rom@4/bev". That is, if the machine needs to boot via a rom I'd prefer qemu state that explicitly.
It is painful in Seabios it is impossible in qemu at all. There is no way for qemu to know about BCVs or BEVs in optionroms especially considering that they are created at runtime like you say bellow. The best qemu can do is to ask user what device user wants to boot from and pass this information to Seabios in form of device path. Seabios (or other firmware) has to figure out how to boot from the device or ignore request if it can't. We can't provide the same functionality as Seabios' f12 menu on qemu command line since content of the menu depend on run time.
BTW, in the situation where seabios has native device support (eg, ATA), I don't have any concerns. (The names are a bit verbose, but that's not really an issue.)
This + network booting are the may use case really. And I do not see what problem we have with BEV devices. "/pci@i0cf8/rom@4/bev" is not much different from "/pci@i0cf8/ethernet@4/ethernet-phy@0" since there can be only one bev per pci device. It is easy for Seabios to see that to boot from pci device in slot 4 func 0 it has to execute BEV.
BTW are you actually aware of any option rom with multiple BCVs and, if yes, how those BCVs differ?
Multiple BCVs - yes. A SCSI card will define a BCV for each attached drive. I don't have a scsi card myself, but the support was added by a user who ran into the problem first hand.
Optionrom is static. How number of BCVs can depend on number of attached drives?
Not sure what you mean by "Optionrom is static". SeaBIOS unlocks the memory, and the optionrom can and will modify itself with additional PNP headers so that it can list multiple BCVs - one for each drive. In particular, gPXE uses self modification to relocate parts of itself into high ram.
"Optionrom is static" was my misunderstanding. As you say here optionrom can create BEVs/BCVs at runtime which make it impossible for qemu to know about them even if qemu examine optionroms of devices.
-- Gleb.
On Sun, Nov 28, 2010 at 09:45:34AM +0200, Gleb Natapov wrote:
On Sat, Nov 27, 2010 at 04:07:45PM -0500, Kevin O'Connor wrote:
On Sat, Nov 27, 2010 at 09:04:24PM +0200, Gleb Natapov wrote:
Suppose we add SCSI support to Seabios and suppose SCSI card Seabios can natively boot from has optionrom. What Seabios will do in such situation and how qemu can know it? Besides qemu support tries to be firmware agnostic.
In such a situation, under my proposal, users wouldn't be able to specify a default boot from their scsi drive until after qemu was also upgraded to know seabios could boot native scsi. (Or, they'd only be able to do it by adding in a command-line option.)
If scsi card has optionrom with only one bcv then Seabios can determine its boot order from device path, so why not provide user with this option today?
It's unclear to me how SeaBIOS is supposed to do that.
Besides qemu may be used to emulates sparc with openbios and this combination may be able to boot from scsi device. Qemu is not just x86 emulator running Seabios. If there is problem with scsi boot we let management know, so it will not create unbootable configuration. Today it is impossible to boot guest from scsi in qemu btw.
Qemu can send in "/pci@i0cf8/scsi@3/disk@0,0" - it's just unclear what seabios is supposed to do with it. (If "ignore it" is the answer, that's fine with me.)
If qemu sends in "/pci@i0cf8/scsi@3/disk@0,0" or "/pci@i0cf8/ethernet@4/ethernet-phy@0" it will expect seabios to boot from the appropriate device. In both cases, seabios would need to run a rom in order to fulfill that request. Trying to figure out which rom is quite painful. That's why I'd prefer to see qemu instead pass in something like "/pci@i0cf8/rom@3/bcv@0" or "/pci@i0cf8/rom@4/bev". That is, if the machine needs to boot via a rom I'd prefer qemu state that explicitly.
It is painful in Seabios it is impossible in qemu at all. There is no way for qemu to know about BCVs or BEVs in optionroms especially considering that they are created at runtime like you say bellow.
It's not impossible - qemu could code up rules for when to request a rom boot and when to request a native boot. That may seem ugly, but (as near as I can tell) it's basically what you've asked seabios to do. If nothing else, qemu has the option to let the user pass in an explicit request via the command-line.
BTW, in the situation where seabios has native device support (eg, ATA), I don't have any concerns. (The names are a bit verbose, but that's not really an issue.)
This + network booting are the may use case really. And I do not see what problem we have with BEV devices. "/pci@i0cf8/rom@4/bev" is not much different from "/pci@i0cf8/ethernet@4/ethernet-phy@0" since there can be only one bev per pci device. It is easy for Seabios to see that to boot from pci device in slot 4 func 0 it has to execute BEV.
I'm still stuck on how seabios is supposed to know it's an ethernet card. Sure, seabios could hardcode translations from classid to strings, but that seems fragile. What happens when the user wants to boot from myranet, or fiberchannel, or whatnot?
Maybe we can compromise here - if the user selects booting from a device, and qemu sees there is a rom for that device, then qemu can specify two boot options:
/pci@i0cf8/ethernet@4/ethernet-phy@0 /pci@i0cf8/rom@4
SeaBIOS will ignore the first entry, and act on the second entry. If at some later point seabios knows how to natively boot from the device (eg, scsi), then it will use the first entry and ignore the second.
BTW, how are PCI locations specified in these paths? They should have a (bus, dev, fn) - your examples only seem to show dev. How are the other parts specified?
-Kevin
On Sun, Nov 28, 2010 at 12:15:44PM -0500, Kevin O'Connor wrote:
On Sun, Nov 28, 2010 at 09:45:34AM +0200, Gleb Natapov wrote:
On Sat, Nov 27, 2010 at 04:07:45PM -0500, Kevin O'Connor wrote:
On Sat, Nov 27, 2010 at 09:04:24PM +0200, Gleb Natapov wrote:
Suppose we add SCSI support to Seabios and suppose SCSI card Seabios can natively boot from has optionrom. What Seabios will do in such situation and how qemu can know it? Besides qemu support tries to be firmware agnostic.
In such a situation, under my proposal, users wouldn't be able to specify a default boot from their scsi drive until after qemu was also upgraded to know seabios could boot native scsi. (Or, they'd only be able to do it by adding in a command-line option.)
If scsi card has optionrom with only one bcv then Seabios can determine its boot order from device path, so why not provide user with this option today?
It's unclear to me how SeaBIOS is supposed to do that.
Suppose we have "/pci@i0cf8/scsi@3/disk@0,0" with boot index 5 in boot devices list and suppose pci device in slot 3 function 0 has optionrom. When Seabios load the option rom from device to memory it looks for string that matches "/pci@i0cf8/.*@3.*" if the string is found option rom gets boot index from it. In our case "/pci@i0cf8/scsi@3/disk@0,0" will match and optionrom will get boot index 5. In practice Seabios will know that device is SCSI by reading device class so it will be able to construct string "/pci@i0cf8/scsi@3" and use simple strstr to find matching device path.
Besides qemu may be used to emulates sparc with openbios and this combination may be able to boot from scsi device. Qemu is not just x86 emulator running Seabios. If there is problem with scsi boot we let management know, so it will not create unbootable configuration. Today it is impossible to boot guest from scsi in qemu btw.
Qemu can send in "/pci@i0cf8/scsi@3/disk@0,0" - it's just unclear what seabios is supposed to do with it. (If "ignore it" is the answer, that's fine with me.)
See above. But for some device paths "ignore it" is acceptable answer (is Seabios can't boot from it and device doesn't have optionrom).
If qemu sends in "/pci@i0cf8/scsi@3/disk@0,0" or "/pci@i0cf8/ethernet@4/ethernet-phy@0" it will expect seabios to boot from the appropriate device. In both cases, seabios would need to run a rom in order to fulfill that request. Trying to figure out which rom is quite painful. That's why I'd prefer to see qemu instead pass in something like "/pci@i0cf8/rom@3/bcv@0" or "/pci@i0cf8/rom@4/bev". That is, if the machine needs to boot via a rom I'd prefer qemu state that explicitly.
It is painful in Seabios it is impossible in qemu at all. There is no way for qemu to know about BCVs or BEVs in optionroms especially considering that they are created at runtime like you say bellow.
It's not impossible - qemu could code up rules for when to request a rom boot and when to request a native boot. That may seem ugly, but (as near as I can tell) it's basically what you've asked seabios to do. If nothing else, qemu has the option to let the user pass in an explicit request via the command-line.
I still do not see why such rule is needed. Why information this patch set provides is not enough?
BTW, in the situation where seabios has native device support (eg, ATA), I don't have any concerns. (The names are a bit verbose, but that's not really an issue.)
This + network booting are the may use case really. And I do not see what problem we have with BEV devices. "/pci@i0cf8/rom@4/bev" is not much different from "/pci@i0cf8/ethernet@4/ethernet-phy@0" since there can be only one bev per pci device. It is easy for Seabios to see that to boot from pci device in slot 4 func 0 it has to execute BEV.
I'm still stuck on how seabios is supposed to know it's an ethernet card. Sure, seabios could hardcode translations from classid to strings, but that seems fragile. What happens when the user wants to boot from myranet, or fiberchannel, or whatnot?
This is not fragile since class to name translation is defined by the spec. But even that is not required if Seabios will be a little bit smarter and will implement fuzzy matching. i.e do not match "/pci@i0cf8/ethernet@4/ethernet-phy@0" exactly but match "/pci@i0cf8/.*@4.*" instead.
Maybe we can compromise here - if the user selects booting from a device, and qemu sees there is a rom for that device, then qemu can specify two boot options:
/pci@i0cf8/ethernet@4/ethernet-phy@0 /pci@i0cf8/rom@4
This patch series implement device paths as defined by Openfirmware spec. /pci@i0cf8/rom@4 sould be out of spec. But I do not see why Seabios can't build later from the former. Also I do not see why it would be needed at all.
SeaBIOS will ignore the first entry, and act on the second entry. If at some later point seabios knows how to natively boot from the device (eg, scsi), then it will use the first entry and ignore the second.
If you let go to the idea of exact matching of string built by qemu in Seabios it will be easy to see that /pci@i0cf8/ethernet@4/ethernet-phy@0 provides everything that Seabios needs to know and even more. If you ignore all the noise it just says "boot from pci device slot 4 fn 0". Seabios may have native support for the card in the slot or it can use option rom on the card. Qemu does not care.
BTW, how are PCI locations specified in these paths? They should have a (bus, dev, fn) - your examples only seem to show dev. How are the other parts specified?
Bus numbers are assigned by a guest. Qemu knows nothing about them, so it specify device path by topology. If pci bridge is present device path will look like this: /pci@i0cf8/pci@2/ethernet@4,1/ethernet-phy@0. This path point to device in slot 4 fn 1 sitting on pci-to-pci bridge in slot 2 fn 0 of host pci controller. Same is true for usb bus.
-- Gleb.
On Sun, Nov 28, 2010 at 08:47:34PM +0200, Gleb Natapov wrote:
On Sun, Nov 28, 2010 at 12:15:44PM -0500, Kevin O'Connor wrote:
It's unclear to me how SeaBIOS is supposed to do that.
Suppose we have "/pci@i0cf8/scsi@3/disk@0,0" with boot index 5 in boot devices list and suppose pci device in slot 3 function 0 has optionrom. When Seabios load the option rom from device to memory it looks for string that matches "/pci@i0cf8/.*@3.*" if the string is found option rom gets boot index from it. In our case "/pci@i0cf8/scsi@3/disk@0,0" will match and optionrom will get boot index 5. In practice Seabios will know that device is SCSI by reading device class so it will be able to construct string "/pci@i0cf8/scsi@3" and use simple strstr to find matching device path.
I recognize that if we had a regex engine in seabios this would work, but I'm reluctant to add one. strstr doesn't work becuase "@3" could match some unrelated part of the path (eg, don't want to match "/pci@i0cf8/scsi@1/disk@3,0") - so, what you seem to want is "/pci@i0cf8/[^/]*@3(/|$)".
[...]
I'm still stuck on how seabios is supposed to know it's an ethernet card. Sure, seabios could hardcode translations from classid to strings, but that seems fragile. What happens when the user wants to boot from myranet, or fiberchannel, or whatnot?
This is not fragile since class to name translation is defined by the spec. But even that is not required if Seabios will be a little bit smarter and will implement fuzzy matching. i.e do not match "/pci@i0cf8/ethernet@4/ethernet-phy@0" exactly but match "/pci@i0cf8/.*@4.*" instead.
I think we're agreeing here that we don't want to put class to name translation in seabios. :-)
Maybe we can compromise here - if the user selects booting from a device, and qemu sees there is a rom for that device, then qemu can specify two boot options:
/pci@i0cf8/ethernet@4/ethernet-phy@0 /pci@i0cf8/rom@4
This patch series implement device paths as defined by Openfirmware spec. /pci@i0cf8/rom@4 sould be out of spec. But I do not see why Seabios can't build later from the former. Also I do not see why it would be needed at all.
The name isn't important to me - call it something else if you want. It's value is that SeaBIOS doesn't then need to do fuzzy matching or parsing of the device names. That is, we turn the list from boot devices to boot methods which makes life easier for the firmware.
SeaBIOS will ignore the first entry, and act on the second entry. If at some later point seabios knows how to natively boot from the device (eg, scsi), then it will use the first entry and ignore the second.
If you let go to the idea of exact matching of string built by qemu in Seabios it will be easy to see that /pci@i0cf8/ethernet@4/ethernet-phy@0 provides everything that Seabios needs to know and even more. If you ignore all the noise it just says "boot from pci device slot 4 fn 0". Seabios may have native support for the card in the slot or it can use option rom on the card. Qemu does not care.
I'm having a hard time letting go of string matching. I understand all the info is there if SeaBIOS parses the string. However, I think parsing out openbios device strings is overkill in an x86 bios that just wants to order the boot objects it knows about.
Is there an issue with qemu generating two strings for devices with roms?
BTW, how are PCI locations specified in these paths? They should have a (bus, dev, fn) - your examples only seem to show dev. How are the other parts specified?
Bus numbers are assigned by a guest. Qemu knows nothing about them, so it specify device path by topology. If pci bridge is present device path will look like this: /pci@i0cf8/pci@2/ethernet@4,1/ethernet-phy@0. This path point to device in slot 4 fn 1 sitting on pci-to-pci bridge in slot 2 fn 0 of host pci controller. Same is true for usb bus.
I understand - it makes sense. This does mean that seabios will need to track where each pci bus comes from.
-Kevin
On Mon, Nov 29, 2010 at 08:34:03PM -0500, Kevin O'Connor wrote:
On Sun, Nov 28, 2010 at 08:47:34PM +0200, Gleb Natapov wrote:
On Sun, Nov 28, 2010 at 12:15:44PM -0500, Kevin O'Connor wrote:
It's unclear to me how SeaBIOS is supposed to do that.
Suppose we have "/pci@i0cf8/scsi@3/disk@0,0" with boot index 5 in boot devices list and suppose pci device in slot 3 function 0 has optionrom. When Seabios load the option rom from device to memory it looks for string that matches "/pci@i0cf8/.*@3.*" if the string is found option rom gets boot index from it. In our case "/pci@i0cf8/scsi@3/disk@0,0" will match and optionrom will get boot index 5. In practice Seabios will know that device is SCSI by reading device class so it will be able to construct string "/pci@i0cf8/scsi@3" and use simple strstr to find matching device path.
I recognize that if we had a regex engine in seabios this would work, but I'm reluctant to add one. strstr doesn't work becuase "@3" could match some unrelated part of the path (eg, don't want to match "/pci@i0cf8/scsi@1/disk@3,0") - so, what you seem to want is "/pci@i0cf8/[^/]*@3(/|$)".
We do not need regex engine to part this very special and regular string. The patch below reads boot order list from qemu and creates rom2prio table for pci roms.
[...]
I'm still stuck on how seabios is supposed to know it's an ethernet card. Sure, seabios could hardcode translations from classid to strings, but that seems fragile. What happens when the user wants to boot from myranet, or fiberchannel, or whatnot?
This is not fragile since class to name translation is defined by the spec. But even that is not required if Seabios will be a little bit smarter and will implement fuzzy matching. i.e do not match "/pci@i0cf8/ethernet@4/ethernet-phy@0" exactly but match "/pci@i0cf8/.*@4.*" instead.
I think we're agreeing here that we don't want to put class to name translation in seabios. :-)
We did? I think it is not needed but I don't not see why it would be a problem.
Maybe we can compromise here - if the user selects booting from a device, and qemu sees there is a rom for that device, then qemu can specify two boot options:
/pci@i0cf8/ethernet@4/ethernet-phy@0 /pci@i0cf8/rom@4
This patch series implement device paths as defined by Openfirmware spec. /pci@i0cf8/rom@4 sould be out of spec. But I do not see why Seabios can't build later from the former. Also I do not see why it would be needed at all.
The name isn't important to me - call it something else if you want. It's value is that SeaBIOS doesn't then need to do fuzzy matching or parsing of the device names. That is, we turn the list from boot devices to boot methods which makes life easier for the firmware.
SeaBIOS will ignore the first entry, and act on the second entry. If at some later point seabios knows how to natively boot from the device (eg, scsi), then it will use the first entry and ignore the second.
If you let go to the idea of exact matching of string built by qemu in Seabios it will be easy to see that /pci@i0cf8/ethernet@4/ethernet-phy@0 provides everything that Seabios needs to know and even more. If you ignore all the noise it just says "boot from pci device slot 4 fn 0". Seabios may have native support for the card in the slot or it can use option rom on the card. Qemu does not care.
I'm having a hard time letting go of string matching. I understand all the info is there if SeaBIOS parses the string. However, I think parsing out openbios device strings is overkill in an x86 bios that just wants to order the boot objects it knows about.
Is there an issue with qemu generating two strings for devices with roms?
I just do not see how I can justify this addition to qemu maintainers given that the parsing code below is very simple.
diff --git a/src/boot.c b/src/boot.c index 021b8ac..c1ac9af 100644 --- a/src/boot.c +++ b/src/boot.c @@ -67,6 +67,47 @@ boot_setup(void) if (!(inb_cmos(CMOS_BIOS_BOOTFLAG1) & 1)) IPL.checkfloppysig = 1; } + + u32 file = romfile_find("bootorder"); + if (!file) + return; + + int filesize = romfile_size(file); + char *f = malloc_tmphigh(filesize); + dprintf(3, "bootorder file found (len %d)\n", filesize); + + if (!f) { + dprintf(1, "can't allocate memory for bootorder file\n"); + return; + } + + romfile_copy(file, f, filesize); + int i; + IPL.fw_bootorder_count = 1; + while(f[i]) { + if (f[i] == '\n') + IPL.fw_bootorder_count++; + i++; + } + IPL.fw_bootorder = malloc_tmphigh(IPL.fw_bootorder_count*sizeof(char*)); + if (!IPL.fw_bootorder) { + dprintf(1, "can't allocate memory for bootorder\n"); + free(f); + return; + } + + dprintf(3, "boot order:\n"); + i = 0; + do { + IPL.fw_bootorder[i] = f; + f = strchr(f, '\n'); + if (*f) { + *f = '\0'; + f++; + dprintf(3, "%d: %s\n", i, IPL.fw_bootorder[i]); + i++; + } + } while(f); }
// Add a BEV vector for a given pnp compatible option rom. @@ -506,3 +547,78 @@ handle_19(void) SET_EBDA(boot_sequence, 0); do_boot(0); } + +/* + * function returns string representing firts device path element in 'dp' + * and puts pointer to the reset of the device path into 'end' + */ +static char *dev_path_get_node(const char *dp, const char **end) +{ + int len; + char *node; + + dp += 1; /* skip '/' */ + + *end = strchr(dp, '/'); + + if (*end == NULL) { + len = strlen(dp); /* last path element */ + *end = dp + len; + } + else + len = *end - dp; + + if (len == 0) + return NULL; + + node = malloc_tmphigh(len + 1); + memcpy(node, dp, len); + node[len] = '\0'; + + return node; +} + +static int match_unit_address(const char *pe, const char *unit_address) +{ + char *s = strchr(pe, '@'); + + if (s == NULL) + return 0; + + return !strcmp(s, unit_address); +} + +#define FW_PCI_DOMAIN "/pci@i0cf8" + +int bootprio_match_pci_device(int dev, int fn) +{ + int i, l; + char pci[7]; + + if (!fn) + l = snprintf(pci, sizeof(pci), "@%x", dev); + else + l = snprintf(pci, sizeof(pci), "@%x,%x", dev, fn); + + for (i = 0; i < IPL.fw_bootorder_count; i++) { + char *node; + const char *next, *path = IPL.fw_bootorder[i]; + int r; + + /* is pci domain? */ + if (memcmp(path, FW_PCI_DOMAIN, strlen(FW_PCI_DOMAIN))) + continue; + + node = dev_path_get_node(path + strlen(FW_PCI_DOMAIN), &next); + if (node == NULL) + continue; + + r = match_unit_address(node, pci); + + free(node); + if (r) + return i; + } + + return -1; +} diff --git a/src/boot.h b/src/boot.h index db046e3..07467e6 100644 --- a/src/boot.h +++ b/src/boot.h @@ -20,6 +20,8 @@ struct ipl_s { int bevcount, bcvcount; u32 bootorder; int checkfloppysig; + char **fw_bootorder; + int fw_bootorder_count; };
#define IPL_TYPE_FLOPPY 0x01 @@ -44,5 +46,6 @@ void add_bcv(u16 seg, u16 ip, u16 desc); struct drive_s; void add_bcv_internal(struct drive_s *drive_g); void boot_prep(void); +int bootprio_match_pci_device(int dev, int fn);
#endif // __BOOT_H diff --git a/src/optionroms.c b/src/optionroms.c index 854c33f..5500c56 100644 --- a/src/optionroms.c +++ b/src/optionroms.c @@ -74,6 +74,13 @@ struct pnp_data { // The end of the last deployed rom. u32 RomEnd = BUILD_ROM_START;
+static struct rom_boot_prio { + u32 addr; + int prio; +} rom2prio[92]; + +static int rom2prio_index; +
/**************************************************************** * Helper functions @@ -342,7 +349,20 @@ init_pcirom(u16 bdf, int isvga) if (! rom) // No ROM present. return -1; - return init_optionrom(rom, bdf, isvga); + + int r = init_optionrom(rom, bdf, isvga); + + if (r || !is_valid_rom(rom)) + return r; + + rom2prio[rom2prio_index].addr = (u32)rom; + rom2prio[rom2prio_index].prio = + bootprio_match_pci_device(pci_bdf_to_dev(bdf), pci_bdf_to_fn(bdf)); + dprintf(3, "pci rom at memory address %x has boot prio %d\n", + rom2prio[rom2prio_index].addr, rom2prio[rom2prio_index].prio); + rom2prio_index++; + + return r; }
diff --git a/src/util.c b/src/util.c index 8e02d1e..cfb4add 100644 --- a/src/util.c +++ b/src/util.c @@ -253,6 +253,17 @@ strtcpy(char *dest, const char *src, size_t len) return dest; }
+// locate first occurance of character c in the string s +char * +strchr(const char *s, int c) +{ + int i = 0; + + while(s[i] && s[i] != c) + i++; + + return s[i] ? (char*)&s[i] : NULL; +}
/**************************************************************** * Keyboard calls diff --git a/src/util.h b/src/util.h index 18ab814..cd46d9c 100644 --- a/src/util.h +++ b/src/util.h @@ -208,6 +208,7 @@ void *memcpy(void *d1, const void *s1, size_t len); void iomemcpy(void *d, const void *s, u32 len); void *memmove(void *d, const void *s, size_t len); char *strtcpy(char *dest, const char *src, size_t len); +char *strchr(const char *s, int c); int get_keystroke(int msec);
// stacks.c -- Gleb.
On Tue, Nov 30, 2010 at 04:01:00PM +0200, Gleb Natapov wrote:
On Mon, Nov 29, 2010 at 08:34:03PM -0500, Kevin O'Connor wrote:
On Sun, Nov 28, 2010 at 08:47:34PM +0200, Gleb Natapov wrote:
If you let go to the idea of exact matching of string built by qemu in Seabios it will be easy to see that /pci@i0cf8/ethernet@4/ethernet-phy@0 provides everything that Seabios needs to know and even more. If you ignore all the noise it just says "boot from pci device slot 4 fn 0". Seabios may have native support for the card in the slot or it can use option rom on the card. Qemu does not care.
I'm having a hard time letting go of string matching. I understand all the info is there if SeaBIOS parses the string. However, I think parsing out openbios device strings is overkill in an x86 bios that just wants to order the boot objects it knows about.
Is there an issue with qemu generating two strings for devices with roms?
I just do not see how I can justify this addition to qemu maintainers given that the parsing code below is very simple.
It doesn't look correct to me - it doesn't handle the case where the PCI device is on a bridge.
BTW, what's the plan for handling SCSI adapters? Lets say a user has a scsi card with three drives (lun 1, lun 3, lun 5) that show up as 3 bcvs (lun1, lun3, lun5 in that order) and the user wishes to boot from lun3. I understand this use case may not be important for qemu, but I'd like to use the same code on coreboot. Being able to boot from any drive is important - it doesn't have to autodetect, but it should be possible.
-Kevin
On Tue, Nov 30, 2010 at 09:53:32PM -0500, Kevin O'Connor wrote:
On Tue, Nov 30, 2010 at 04:01:00PM +0200, Gleb Natapov wrote:
On Mon, Nov 29, 2010 at 08:34:03PM -0500, Kevin O'Connor wrote:
On Sun, Nov 28, 2010 at 08:47:34PM +0200, Gleb Natapov wrote:
If you let go to the idea of exact matching of string built by qemu in Seabios it will be easy to see that /pci@i0cf8/ethernet@4/ethernet-phy@0 provides everything that Seabios needs to know and even more. If you ignore all the noise it just says "boot from pci device slot 4 fn 0". Seabios may have native support for the card in the slot or it can use option rom on the card. Qemu does not care.
I'm having a hard time letting go of string matching. I understand all the info is there if SeaBIOS parses the string. However, I think parsing out openbios device strings is overkill in an x86 bios that just wants to order the boot objects it knows about.
Is there an issue with qemu generating two strings for devices with roms?
I just do not see how I can justify this addition to qemu maintainers given that the parsing code below is very simple.
It doesn't look correct to me - it doesn't handle the case where the PCI device is on a bridge.
This is because Seabios does not yet keep pci bus topology information. Given this information it is very easy to add bridge support to my code. dev_path_get_node() returns pointer to next node for purpose :)
BTW, what's the plan for handling SCSI adapters? Lets say a user has a scsi card with three drives (lun 1, lun 3, lun 5) that show up as 3 bcvs (lun1, lun3, lun5 in that order) and the user wishes to boot from lun3. I understand this use case may not be important for qemu, but I'd like to use the same code on coreboot. Being able to boot from any drive is important - it doesn't have to autodetect, but it should be possible.
We can't. Option rom does not give us back enough information to do so. Form device path we know exactly what id:lun boot should be done from, but pnp_data does not have information to map BCV back to id:lun. I do not see how coreboot can provide better information to Seabios then qemu here. BTW to create proper EDD entry for SCSI boot device BIOS also needs too map BCV to id:lun. How it can be done?
SCSI _is_ important for qemu. Not HBA we have now, but something supported by recent operation systems out of the box. When such HBA will be emulated in qemu we will add native Seabios support for it.
-- Gleb.
On Wed, Dec 01, 2010 at 02:27:40PM +0200, Gleb Natapov wrote:
On Tue, Nov 30, 2010 at 09:53:32PM -0500, Kevin O'Connor wrote:
BTW, what's the plan for handling SCSI adapters? Lets say a user has a scsi card with three drives (lun 1, lun 3, lun 5) that show up as 3 bcvs (lun1, lun3, lun5 in that order) and the user wishes to boot from lun3. I understand this use case may not be important for qemu, but I'd like to use the same code on coreboot. Being able to boot from any drive is important - it doesn't have to autodetect, but it should be possible.
We can't. Option rom does not give us back enough information to do so. Form device path we know exactly what id:lun boot should be done from, but pnp_data does not have information to map BCV back to id:lun. I do not see how coreboot can provide better information to Seabios then qemu here.
You're thinking in terms of which device to boot, which does make this difficult. However, it's equally valid to think in terms of which boot method to invoke, which makes this easy.
We could tell the coreboot user to edit the "bootorder" file and add "/pci@i0cf8/rom1@4" (second rom on 4th pci device - the exact syntax of the name is not important).
BTW to create proper EDD entry for SCSI boot device BIOS also needs too map BCV to id:lun. How it can be done?
It's the responsibility of the rom to build the EDD info. I don't know if all roms do this - I don't believe it's possible to get at the EDD info until after the drive has been mapped (ie, too late to use it for boot ordering).
SCSI _is_ important for qemu. Not HBA we have now, but something supported by recent operation systems out of the box. When such HBA will be emulated in qemu we will add native Seabios support for it.
I understand. However, we'll still need to support arbitrary rom based BEVs and BCVs, so the use case is still important.
-Kevin
On Wed, Dec 01, 2010 at 09:25:40PM -0500, Kevin O'Connor wrote:
On Wed, Dec 01, 2010 at 02:27:40PM +0200, Gleb Natapov wrote:
On Tue, Nov 30, 2010 at 09:53:32PM -0500, Kevin O'Connor wrote:
BTW, what's the plan for handling SCSI adapters? Lets say a user has a scsi card with three drives (lun 1, lun 3, lun 5) that show up as 3 bcvs (lun1, lun3, lun5 in that order) and the user wishes to boot from lun3. I understand this use case may not be important for qemu, but I'd like to use the same code on coreboot. Being able to boot from any drive is important - it doesn't have to autodetect, but it should be possible.
We can't. Option rom does not give us back enough information to do so. Form device path we know exactly what id:lun boot should be done from, but pnp_data does not have information to map BCV back to id:lun. I do not see how coreboot can provide better information to Seabios then qemu here.
You're thinking in terms of which device to boot, which does make this difficult. However, it's equally valid to think in terms of which boot method to invoke, which makes this easy.
It is not. Because boot methods are enumerated by a guest at runtime. Qemu knows absolutely nothing about them. I am thinking in terms of devices because this is the only thing I have in qemu. BBS specification is broken since it doesn't provide a way for discovered boot method (BCV) to be linked back to a device it will boot from. Nothing we can do to fix this except moving to EFI (an hope the problem is fixed there).
We could tell the coreboot user to edit the "bootorder" file and add "/pci@i0cf8/rom1@4" (second rom on 4th pci device - the exact syntax of the name is not important).
But how user should knows that second rom (I think you mean "second BCV") on pci device 4.0 will boot from the new scsi cdrom that he just connected? How can he tell that it should put second BCV there and not third or fifth without running Seabios first and looking at F12 menu? Depending on option rom implementation even F12 menu can have not enough information for user to guess which boot entry he should use to boot from the device because product name that is used to distinguish between different boot entires should be unique, but not necessary provide useful information about device according to spec. (Both gpxe and lsi 8xx_64.rom provide device address as part of product name; gpxe puts pci address there and 8xx_64.rom puts ID LUN). Another important point is that BCV number can change when new device is added to scsi bus, so next boot will mysteriously fail. Important property of device path that it is stable and does not depend on HW configuration.
BTW to create proper EDD entry for SCSI boot device BIOS also needs too map BCV to id:lun. How it can be done?
It's the responsibility of the rom to build the EDD info. I don't know if all roms do this - I don't believe it's possible to get at the EDD info until after the drive has been mapped (ie, too late to use it for boot ordering).
How can we get to EDD info after device is mapped? Looking at Seabios implementation it builds EDD table on the fly when int_1348 is called and it does it only for internal devices. Can we use "disconnect vector" to connect device temporarily get EDD and then disconnect?
SCSI _is_ important for qemu. Not HBA we have now, but something supported by recent operation systems out of the box. When such HBA will be emulated in qemu we will add native Seabios support for it.
I understand. However, we'll still need to support arbitrary rom based BEVs and BCVs, so the use case is still important.
We can't do something that is impossible. For coreboot Seabios should implement what BBS spec says i.e enumerate all BCVs, present boot menu to the user, record number of BCVs and user's choice on non-volatile storage (CMOS). On next boot use recorded user's choice unless number of BCVs changes, otherwise present boot menu again. This is of course broken too since number of BCVs may not change even if HW configuration changes substantially. Spec says that in that case user probably will want to adjust boot order anyway and will enter boot menu by itself. Sorry excuse for failing to provide proper functionality if you ask me :)
-- Gleb.
Gleb Natapov wrote:
BBS specification is broken since it doesn't provide a way for discovered boot method (BCV) to be linked back to a device it will boot from. Nothing we can do to fix this except moving to EFI (an hope the problem is fixed there).
There is that option, or there could be some simple improvement of our own, which works in QEMU and maybe even adds value to coreboot. But then there would be a bit of novel development in firmware - that can't be a good thing, right?
Spec says that in that case user probably will want to adjust boot order anyway and will enter boot menu by itself. Sorry excuse for failing to provide proper functionality if you ask me :)
I agree. I can not believe the absolute resistance to innovation in this field.
Isn't the scope of BBS logic limited to boot time? (There are calls to do settings, but that's no problem.)
Maybe it would be possible for SeaBIOS to provide what looks like BBS to the guest, but on the other side there is something more intelligent going on, be it together with QEMU or coreboot?
//Peter
On Thu, Dec 02, 2010 at 04:07:16PM +0100, Peter Stuge wrote:
Gleb Natapov wrote:
BBS specification is broken since it doesn't provide a way for discovered boot method (BCV) to be linked back to a device it will boot from. Nothing we can do to fix this except moving to EFI (an hope the problem is fixed there).
There is that option, or there could be some simple improvement of our own, which works in QEMU and maybe even adds value to coreboot. But then there would be a bit of novel development in firmware - that can't be a good thing, right?
I am all for novel development in firmware, but unfortunately I do not see what can we do in Seabios + qemu to fix this shortcoming. The problem should be fixed in each and every option rom. Option rom may set device address somewhere in pnp header for instance.
Spec says that in that case user probably will want to adjust boot order anyway and will enter boot menu by itself. Sorry excuse for failing to provide proper functionality if you ask me :)
I agree. I can not believe the absolute resistance to innovation in this field.
Interested parties want everyone to move to EFI I guess.
Isn't the scope of BBS logic limited to boot time? (There are calls to do settings, but that's no problem.)
Maybe it would be possible for SeaBIOS to provide what looks like BBS to the guest, but on the other side there is something more intelligent going on, be it together with QEMU or coreboot?
I don't how it can be done without cooperation with option roms.
-- Gleb.
Gleb Natapov wrote:
How can we get to EDD info after device is mapped? Looking at Seabios implementation it builds EDD table on the fly when int_1348 is called and it does it only for internal devices. Can we use "disconnect vector" to connect device temporarily get EDD and then disconnect?
From BIOS Boot Specification 1.01
"6.4.2 Disconnect Vector
Originally, it was thought that the DV would be called by the BIOS if the device's BCV was called and subsequent booting from the device failed. However, it was later discovered that current PnP option ROMs are more well behaved by checking during the BCV call if their device will properly respond to INT 13h calls or not, and simply not hooking INT 13h if those calls would fail. Because of this, the DV is not called by a BIOS supporting the BIOS Boot Specification, nor is it necessary to have a valid DV in the PnP Expansion Header. The DV should be NULL and can't be used for other storage."
Sebastian
On Thu, Dec 02, 2010 at 02:30:42PM +0200, Gleb Natapov wrote:
On Wed, Dec 01, 2010 at 09:25:40PM -0500, Kevin O'Connor wrote:
You're thinking in terms of which device to boot, which does make this difficult. However, it's equally valid to think in terms of which boot method to invoke, which makes this easy.
It is not. Because boot methods are enumerated by a guest at runtime. Qemu knows absolutely nothing about them. I am thinking in terms of devices because this is the only thing I have in qemu.
As before, a safe heuristic would be to request a rom boot for any device with a pci rom that the user requests to boot from.
Note, your original proposal included a boot method: /rom@genroms/linuxboot.bin I'm asking to extend this to be able to include roms on PCI devices.
We could tell the coreboot user to edit the "bootorder" file and add "/pci@i0cf8/rom1@4" (second rom on 4th pci device - the exact syntax of the name is not important).
But how user should knows that second rom (I think you mean "second BCV") on pci device 4.0 will boot from the new scsi cdrom that he just connected? How can he tell that it should put second BCV there and not third or fifth without running Seabios first and looking at F12 menu?
Exactly - look at the F12 menu. (Or, for bonus points, one could write a program that scans roms on the booted coreboot system, presents the user with a menu, and then writes the requested boot method to "bootorder".)
Being able to specify which boot method is a requirement for me. It doesn't have to be pretty, but it does have to be possible.
BTW to create proper EDD entry for SCSI boot device BIOS also needs too map BCV to id:lun. How it can be done?
It's the responsibility of the rom to build the EDD info. I don't know if all roms do this - I don't believe it's possible to get at the EDD info until after the drive has been mapped (ie, too late to use it for boot ordering).
How can we get to EDD info after device is mapped?
Raise int 0x13 ah=0x48 - once the drive is mapped it will hook that the 0x13 irq and handle the request (or jump to the bios handler for drives it doesn't know about).
Can we use "disconnect vector" to connect device temporarily get EDD and then disconnect?
No.
I understand. However, we'll still need to support arbitrary rom based BEVs and BCVs, so the use case is still important.
We can't do something that is impossible.
You've used this word "impossible" a few times - I'm afraid I don't know what it means.
For coreboot Seabios should implement what BBS spec says i.e enumerate all BCVs, present boot menu to the user, record number of BCVs and user's choice on non-volatile storage (CMOS).
Bleh - there's no need for that. Much more reliable is to record the device path for builtin devices or the boot method (device path of rom, plus bev/bcv instance) for rom based boots.
-Kevin
On Thu, Dec 02, 2010 at 09:01:25PM -0500, Kevin O'Connor wrote:
On Thu, Dec 02, 2010 at 02:30:42PM +0200, Gleb Natapov wrote:
On Wed, Dec 01, 2010 at 09:25:40PM -0500, Kevin O'Connor wrote:
You're thinking in terms of which device to boot, which does make this difficult. However, it's equally valid to think in terms of which boot method to invoke, which makes this easy.
It is not. Because boot methods are enumerated by a guest at runtime. Qemu knows absolutely nothing about them. I am thinking in terms of devices because this is the only thing I have in qemu.
As before, a safe heuristic would be to request a rom boot for any device with a pci rom that the user requests to boot from.
Note, your original proposal included a boot method: /rom@genroms/linuxboot.bin I'm asking to extend this to be able to include roms on PCI devices.
I already posted here code that maps PCI rom to PCI device path. Why do you still insist on artificial path like /pci/rom@4?
We could tell the coreboot user to edit the "bootorder" file and add "/pci@i0cf8/rom1@4" (second rom on 4th pci device - the exact syntax of the name is not important).
But how user should knows that second rom (I think you mean "second BCV") on pci device 4.0 will boot from the new scsi cdrom that he just connected? How can he tell that it should put second BCV there and not third or fifth without running Seabios first and looking at F12 menu?
Exactly - look at the F12 menu. (Or, for bonus points, one could write a program that scans roms on the booted coreboot system, presents the user with a menu, and then writes the requested boot method to "bootorder".)
If you propose that then you probably misunderstand the problem I am trying to tackle. Qemu should be able to specify boot order for newly created machine with arbitrary HW configuration without making user to look at F12 menu. Actually at this point there is not human user at all. All the process from machine creation till OS installation is completely unattended. Looking at the BBS spec in several places they say that if NV ram is corrupted bios should use some predefined default boot order. This "predefined default boot order" is what qemu tries to pass to Seabios to use correct boot device without user's input.
To make it clear "unattended" part is absolute requirement.
Being able to specify which boot method is a requirement for me. It doesn't have to be pretty, but it does have to be possible.
For you problem solution is very easy and described in BBS spec. You just need two numbers IPL to boot from and which BCV is first. No need for device paths at all. In fact Seabios already tracks IPL order this way the only thing missing is to track BCV order.
BTW to create proper EDD entry for SCSI boot device BIOS also needs too map BCV to id:lun. How it can be done?
It's the responsibility of the rom to build the EDD info. I don't know if all roms do this - I don't believe it's possible to get at the EDD info until after the drive has been mapped (ie, too late to use it for boot ordering).
How can we get to EDD info after device is mapped?
Raise int 0x13 ah=0x48 - once the drive is mapped it will hook that the 0x13 irq and handle the request (or jump to the bios handler for drives it doesn't know about).
Can we use "disconnect vector" to connect device temporarily get EDD and then disconnect?
No.
And is it possible to call BCV and then restore int13 vector? So to find out what device each BCV belongs too we do: foreach(bcv) call_bcv(bcv) int 1348 restor(int13)
After that we call call_bcv(bcv) but in correct order.
I understand. However, we'll still need to support arbitrary rom based BEVs and BCVs, so the use case is still important.
We can't do something that is impossible.
You've used this word "impossible" a few times - I'm afraid I don't know what it means.
It means that I do not have a solution and you do not propose one either :) It seems we were trying to solve differed problems though. I hope now it is much more clear what I am trying to achieve with proposed bootorder patches.
For coreboot Seabios should implement what BBS spec says i.e enumerate all BCVs, present boot menu to the user, record number of BCVs and user's choice on non-volatile storage (CMOS).
Bleh - there's no need for that. Much more reliable is to record the device path for builtin devices or the boot method (device path of rom, plus bev/bcv instance) for rom based boots.
Why is this much more reliable? Suppose user has scsi card with 3 devices id3 id5 id6. Three BCVs was created for them and user chose to boot from BCV3(id6). He added /pci/scsi@4/bcv@3 to his coreboot's bootorder file. Now he adds one more device to this scsi bus with id1. On the next boot 4 BCVs will be created and now id6 is bootable by BCV4 instead BCV3. The result is unbootable system.
-- Gleb.
Hi,
If scsi card has optionrom with only one bcv then Seabios can determine its boot order from device path, so why not provide user with this option today?
It's unclear to me how SeaBIOS is supposed to do that.
Try to keep track of which bcv/bev belongs to which pci device? It should surely work for devices supported by seabios natively. SeaBIOS should also know which device's rom registered which entry. It might become tricky though in case there are multiple identical devices are present, say two e1000 cards, where the first rom could register entries for both cards ...
Maybe we can compromise here - if the user selects booting from a device, and qemu sees there is a rom for that device, then qemu can specify two boot options:
/pci@i0cf8/ethernet@4/ethernet-phy@0 /pci@i0cf8/rom@4
SeaBIOS will ignore the first entry, and act on the second entry.
SeaBIOS should be able to operate just fine with the first entry. "ethernet@4" means "the nic at bus address 4". As this is a PCI bus "4" is the pci address. So SeaBIOS would just look what entries it has for "00:04.0", run the rom, and ignore the "/ethernet-phy@0" part as it can't handle it.
In case of scsi seabios can look at the next path element to figure the scsi id. With native support it should be able to boot the correct disk directly. When booting via rom it can either just pick the first entry unconditionally (probably good enougth in 99% of the cases) or do some guesswork based on the order the entries are registered.
BTW, how are PCI locations specified in these paths? They should have a (bus, dev, fn) - your examples only seem to show dev. How are the other parts specified?
fn is optional for fn=0, IIRC the syntax is "$class@$dev,$fn".
Bus is specified via location in the tree, i.e. you'll see the bridge for the secondary pci bus in the path, like this:
/pci@i0cf8/bridge@7/ethernet@3/...
(not sure it is actually named 'bridge' in the openfirmware specs though).
cheers, Gerd
On Mon, Nov 29, 2010 at 11:50:45AM +0100, Gerd Hoffmann wrote:
If scsi card has optionrom with only one bcv then Seabios can determine its boot order from device path, so why not provide user with this option today?
It's unclear to me how SeaBIOS is supposed to do that.
Try to keep track of which bcv/bev belongs to which pci device? It should surely work for devices supported by seabios natively.
No issues for any device with native support. I'm okay with the proposed syntax.
SeaBIOS should also know which device's rom registered which entry.
It doesn't today, but that shouldn't be an issue to add.
It might become tricky though in case there are multiple identical devices are present, say two e1000 cards, where the first rom could register entries for both cards ...
Right - here's where things get complicated.
Maybe we can compromise here - if the user selects booting from a device, and qemu sees there is a rom for that device, then qemu can specify two boot options:
/pci@i0cf8/ethernet@4/ethernet-phy@0 /pci@i0cf8/rom@4
SeaBIOS will ignore the first entry, and act on the second entry.
SeaBIOS should be able to operate just fine with the first entry. "ethernet@4" means "the nic at bus address 4". As this is a PCI bus "4" is the pci address. So SeaBIOS would just look what entries it has for "00:04.0", run the rom, and ignore the "/ethernet-phy@0" part as it can't handle it.
Right - I'm not happy about trying to parse out openbios device descriptors though. The natural flow (as I see it) is for seabios to find all the boot methods in the system and then see which ones have been requested to be prioritized. Trying to do fuzzy matching of found device to requested device just seems like an unnecessary pain IMO.
When booting via rom it can either just pick the first entry unconditionally (probably good enougth in 99% of the cases) or do some guesswork based on the order the entries are registered.
I guess that's the crux of the matter - I'd rather not do guessing in the firmware. The emulator is in a much better position to do heuristics and guessing - if nothing else, the emulator can allow the user to pass it in on the command-line.
BTW, how are PCI locations specified in these paths? They should have a (bus, dev, fn) - your examples only seem to show dev. How are the other parts specified?
fn is optional for fn=0, IIRC the syntax is "$class@$dev,$fn".
Bus is specified via location in the tree, i.e. you'll see the bridge for the secondary pci bus in the path, like this:
/pci@i0cf8/bridge@7/ethernet@3/...
(not sure it is actually named 'bridge' in the openfirmware specs though).
Thanks.
-Kevin
On Mon, Nov 29, 2010 at 08:55:09PM -0500, Kevin O'Connor wrote:
On Mon, Nov 29, 2010 at 11:50:45AM +0100, Gerd Hoffmann wrote:
If scsi card has optionrom with only one bcv then Seabios can determine its boot order from device path, so why not provide user with this option today?
It's unclear to me how SeaBIOS is supposed to do that.
Try to keep track of which bcv/bev belongs to which pci device? It should surely work for devices supported by seabios natively.
No issues for any device with native support. I'm okay with the proposed syntax.
SeaBIOS should also know which device's rom registered which entry.
It doesn't today, but that shouldn't be an issue to add.
It might become tricky though in case there are multiple identical devices are present, say two e1000 cards, where the first rom could register entries for both cards ...
Right - here's where things get complicated.
I don't see how it can be solved at all given that bev->productname doesn't have any structure so it can't be parsed back to device's pci address.
Maybe we can compromise here - if the user selects booting from a device, and qemu sees there is a rom for that device, then qemu can specify two boot options:
/pci@i0cf8/ethernet@4/ethernet-phy@0 /pci@i0cf8/rom@4
SeaBIOS will ignore the first entry, and act on the second entry.
SeaBIOS should be able to operate just fine with the first entry. "ethernet@4" means "the nic at bus address 4". As this is a PCI bus "4" is the pci address. So SeaBIOS would just look what entries it has for "00:04.0", run the rom, and ignore the "/ethernet-phy@0" part as it can't handle it.
Right - I'm not happy about trying to parse out openbios device descriptors though. The natural flow (as I see it) is for seabios to find all the boot methods in the system and then see which ones have been requested to be prioritized. Trying to do fuzzy matching of found device to requested device just seems like an unnecessary pain IMO.
When booting via rom it can either just pick the first entry unconditionally (probably good enougth in 99% of the cases) or do some guesswork based on the order the entries are registered.
I guess that's the crux of the matter - I'd rather not do guessing in the firmware. The emulator is in a much better position to do heuristics and guessing - if nothing else, the emulator can allow the user to pass it in on the command-line.
Actually Seabios is in a much better position to do this heuristics since only at runtime all IPLs are knows. What heuristics you think emulator can implement?
BTW, how are PCI locations specified in these paths? They should have a (bus, dev, fn) - your examples only seem to show dev. How are the other parts specified?
fn is optional for fn=0, IIRC the syntax is "$class@$dev,$fn".
Bus is specified via location in the tree, i.e. you'll see the bridge for the secondary pci bus in the path, like this:
/pci@i0cf8/bridge@7/ethernet@3/...
(not sure it is actually named 'bridge' in the openfirmware specs though).
Thanks.
-Kevin
-- Gleb.
Gleb Natapov wrote:
There is no way for qemu to know about BCVs or BEVs
This is very much the key point.
In order to have command line control over the boot process, the machine and the firmware must agree on things.
I see two options:
1. QEMU works very very hard to provide a machine that will result in a particular BBS program flow in firmware, in the end resulting in the desired device being used for booting - as long as QEMU and the firmware happen to have the same understanding of the BBS.
2. QEMU passes boot instructions to the firmware based on immediate, common, structured data.
The first option seems disgusting to me, because it has many drawbacks and no benefits.
The second option requires inventing something that goes beyond the established BIOS standards, maybe a reason for it to see fierce resistance, but it is the only thing that makes sense.
Specifying boot device using PCI BDF is a great example of using common structured data. That BDF exists both in machine and firmware data models. The scope of BBS is limited to the firmware, so it is not really practical for creating consistency in a dynamic machine.
//Peter
Peter Stuge wrote:
Specifying boot device using PCI BDF is a great example of using common structured data. That BDF exists both in machine and firmware data models.
Gleb Natapov wrote:
Bus numbers are assigned by a guest. Qemu knows nothing about them, so it specify device path by topology.
Quite. By BDF I of course mean topology. ;)
The BDF itself is not much better than a BBS concept, since only the firmware knows the details.
But the topology is common, even if bus number differs between machine and firmware.
How is the topology structured? I'm not sure that firmware can use a "slot" number. Device number on the bus works, is that what you mean?
//Peter
On Sun, Nov 28, 2010 at 08:11:45PM +0100, Peter Stuge wrote:
Peter Stuge wrote:
Specifying boot device using PCI BDF is a great example of using common structured data. That BDF exists both in machine and firmware data models.
Gleb Natapov wrote:
Bus numbers are assigned by a guest. Qemu knows nothing about them, so it specify device path by topology.
Quite. By BDF I of course mean topology. ;)
Ah, then we are in violent agreement :)
The BDF itself is not much better than a BBS concept, since only the firmware knows the details.
Yeap.
But the topology is common, even if bus number differs between machine and firmware.
Correct.
How is the topology structured? I'm not sure that firmware can use a "slot" number. Device number on the bus works, is that what you mean?
To specify device path to PCI card using topology one needs to specify slot.fn of all pci-to-pci buses from pci host controller to pci device in question.
-- Gleb.
On Sun, Nov 28, 2010 at 08:00:29PM +0100, Peter Stuge wrote:
Gleb Natapov wrote:
There is no way for qemu to know about BCVs or BEVs
This is very much the key point.
In order to have command line control over the boot process, the machine and the firmware must agree on things.
I see two options:
- QEMU works very very hard to provide a machine that will result in
a particular BBS program flow in firmware, in the end resulting in the desired device being used for booting - as long as QEMU and the firmware happen to have the same understanding of the BBS.
Since qemu knows nothing about BCVs and BEVs it can't implement 1 since it can't know what BBS flow will look like in Seabios.
- QEMU passes boot instructions to the firmware based on immediate,
common, structured data.
What is this "immediate, common, structured data"? This is the crux of the problem really.
The first option seems disgusting to me, because it has many drawbacks and no benefits.
The second option requires inventing something that goes beyond the established BIOS standards, maybe a reason for it to see fierce resistance, but it is the only thing that makes sense.
Specifying boot device using PCI BDF is a great example of using common structured data. That BDF exists both in machine and firmware data models. The scope of BBS is limited to the firmware, so it is not really practical for creating consistency in a dynamic machine.
B from BDF does not exists in machine data model.
-- Gleb.