> On May 19, 2021, at 12:21 PM, Jung-uk Kim <j...@freebsd.org> wrote: > > On 21. 5. 19., Jung-uk Kim wrote: >> On 21. 5. 19., John Nielsen wrote: >>>> On May 17, 2021, at 2:27 PM, Jung-uk Kim <junguk....@gmail.com> wrote: >>>> >>>> On 21. 5. 17., John Nielsen wrote: >>>>> I’m not much of a kernel programmer but I’m trying to maintain/improve >>>>> the isboot module, which allows booting directly from iSCSI by reading >>>>> the iSCSI Boot Firmware Table (iBFT), bringing up the interface with the >>>>> details specified therein and connecting to the specified iSCSI target >>>>> before trying to mount root. >>>>> >>>>> I’m not the original author but as the port maintainer I am hosting the >>>>> code here: https://github.com/jnielsendotnet/isboot >>>>> >>>>> I have a test system where the module loads but fails to find the iBFT. I >>>>> reviewed the iBFT code and realized it has a bunch of magic numbers mixed >>>>> in with some random memory diving. If I’m reading it right (see >>>>> https://github.com/jnielsendotnet/isboot/blob/master/src/ibft.h#L37 and >>>>> https://github.com/jnielsendotnet/isboot/blob/master/src/ibft.c#L521), it >>>>> looks like it scans all of the (kernel?) memory between 512K and 1M in >>>>> 16-byte increments looking for one beginning with the string “iBFT”, >>>>> which if it finds will be used as the offset for reading the table. I >>>>> don’t know where the 512K and 1M values came from or if they are correct, >>>>> but I do have a system where that method does not work. >>>>> >>>>> IIUC, the iBFT is an ACPI table, and it seems like using ACPI to find it >>>>> would be safer and more reliable. So my question is: how does one do >>>>> that? Are there other places in the kernel code that do this sort of >>>>> thing that I could use as a model? Any gotchas I should know about as a >>>>> (less-than) novice kernel programmer? >>>> >>>> You may use AcpiGetTable() and AcpiPutTable(), e.g., >>>> >>>> status = AcpiGetTable(ACPI_SIG_IBFT, …); >>> >>> Thank you (and Andriy) for your responses. Good to know that ACPI_SIG_IBFT >>> is already defined in the upstream headers. >> >> It seems there are two methods. >> >> ftp://ftp.software.ibm.com/systems/support/bladecenter/iscsi_boot_firmware_table_v1.03.pdf >> >> 1.4.3.1 Locating the iBFT >> >> The iBFT is located by the following methods. A platform shall implement >> one or more of these methods. >> >> 1. The ACPI Method. The iBFT is pointed to by an entry in the RSDT/XSDT. >> Note that ACPI [ACPI=3.0b] specifies the string in the pointer as >> “IBFT” (all upper case) HOWEVER the signature in the table being pointed >> to is“iBFT” (note the mixed case). >> >> 2. The Low RAM Method. Scan for the table header signature in system >> memory between 512K and 1024K. The scan MUST be done starting at >> the lower address scanning forward to the higher address. When using the >> Low RAM Method the table header must be aligned on a 16-byte >> boundary. >> >> Note: A system operating in UEFI mode shall utilize only the ACPI method. >> >> For modern system, it seems you should be using Method 1. I don't >> understand the "HOWEVER" part, though. > > I did little more research. It seems iSCSI spec. predates ACPI > standardization and IBM kept on using "iBFT" instead of ACPI spec. > "IBFT". Because this confusion, some systems use "iBFT" and some use > "IBFT". Therefore, it seems you need to test both, e.g., > > status = AcpiGetTable(ACPI_SIG_IBFT, 0, &ibft); > if (ACPI_FAILURE(status)) > status = AcpiGetTable("iBFT", 0, &ibft);
Very helpful once again, thank you. My test machine (either the motherboard or the NIC) has a buggy BIOS that prevents it from booting in legacy mode with iSCSI so I’m using UEFI whether I wanted to or not. I’m glad that my theory that the Low RAM Method might not work in UEFI has some merit. I did notice that Linux looks for both iBFT and IBFT in its driver; the existence of two standards is alluded to in the comments but it’s nice to know what they are. I’ll adopt your suggested approach. JN