Date: Wed, 19 May 2021 21:41:56 -0600 From: John Nielsen <lists@jnielsen.net> To: Jung-uk Kim <jkim@freebsd.org> Cc: "freebsd-acpi@freebsd.org" <freebsd-acpi@FreeBSD.org> Subject: Re: How to properly locate/parse ACPI table from kernel module? Message-ID: <291E1068-2F9A-4C6B-B7F7-D47B112A2BE5@jnielsen.net> In-Reply-To: <f960181c-7c23-f4a1-2754-5be14bba5991@FreeBSD.org> References: <BCFCDCE9-F169-4C1C-AD0C-FDE511C0BC11@jnielsen.net> <6e1f13bd-dc8f-6b30-2b62-2841deea8781@gmail.com> <A63CF8E2-F185-495A-99C1-421781356D8B@jnielsen.net> <9f50a0af-9d33-cbdb-7458-a8ffcbabb0be@gmail.com> <f960181c-7c23-f4a1-2754-5be14bba5991@FreeBSD.org>
next in thread | previous in thread | raw e-mail | index | archive | help
--Apple-Mail=_CA23D759-B102-45E6-AA8F-5B26F2CA9D0F Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=utf-8 > On May 19, 2021, at 12:21 PM, Jung-uk Kim <jkim@freebsd.org> wrote: >=20 > 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.kim@gmail.com> = wrote: >>>>=20 >>>> On 21. 5. 17., John Nielsen wrote: >>>>> I=E2=80=99m not much of a kernel programmer but I=E2=80=99m 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. >>>>>=20 >>>>> I=E2=80=99m not the original author but as the port maintainer I = am hosting the code here: https://github.com/jnielsendotnet/isboot >>>>>=20 >>>>> 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=E2=80=99m 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 = =E2=80=9CiBFT=E2=80=9D, which if it finds will be used as the offset for = reading the table. I don=E2=80=99t 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. >>>>>=20 >>>>> 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? >>>>=20 >>>> You may use AcpiGetTable() and AcpiPutTable(), e.g., >>>>=20 >>>> status =3D AcpiGetTable(ACPI_SIG_IBFT, =E2=80=A6); >>>=20 >>> Thank you (and Andriy) for your responses. Good to know that = ACPI_SIG_IBFT is already defined in the upstream headers. >>=20 >> It seems there are two methods. >>=20 >> = ftp://ftp.software.ibm.com/systems/support/bladecenter/iscsi_boot_firmware= _table_v1.03.pdf >>=20 >> 1.4.3.1 Locating the iBFT >>=20 >> The iBFT is located by the following methods. A platform shall = implement >> one or more of these methods. >>=20 >> 1. The ACPI Method. The iBFT is pointed to by an entry in the = RSDT/XSDT. >> Note that ACPI [ACPI=3D3.0b] specifies the string in the pointer as >> =E2=80=9CIBFT=E2=80=9D (all upper case) HOWEVER the signature in the = table being pointed >> to is=E2=80=9CiBFT=E2=80=9D (note the mixed case). >>=20 >> 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. >>=20 >> Note: A system operating in UEFI mode shall utilize only the ACPI = method. >>=20 >> For modern system, it seems you should be using Method 1. I don't >> understand the "HOWEVER" part, though. >=20 > 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., >=20 > status =3D AcpiGetTable(ACPI_SIG_IBFT, 0, &ibft); > if (ACPI_FAILURE(status)) > status =3D 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=E2=80=99m using UEFI whether I wanted to = or not. I=E2=80=99m 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=E2=80=99s = nice to know what they are. I=E2=80=99ll adopt your suggested approach. JN --Apple-Mail=_CA23D759-B102-45E6-AA8F-5B26F2CA9D0F Content-Transfer-Encoding: quoted-printable Content-Type: text/html; charset=utf-8 <html><head><meta http-equiv=3D"Content-Type" content=3D"text/html; = charset=3Dutf-8"></head><body style=3D"word-wrap: break-word; = -webkit-nbsp-mode: space; line-break: after-white-space;" = class=3D""><div><blockquote type=3D"cite" class=3D""><div class=3D"">On = May 19, 2021, at 12:21 PM, Jung-uk Kim <<a = href=3D"mailto:jkim@freebsd.org" class=3D"">jkim@freebsd.org</a>> = wrote:</div><br class=3D"Apple-interchange-newline"><div class=3D""><meta = charset=3D"UTF-8" class=3D""><span style=3D"caret-color: rgb(0, 0, 0); = font-family: Helvetica; font-size: 12px; font-style: normal; = font-variant-caps: normal; font-weight: normal; letter-spacing: normal; = text-align: start; text-indent: 0px; text-transform: none; white-space: = normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; = text-decoration: none; float: none; display: inline !important;" = class=3D"">On 21. 5. 19., Jung-uk Kim wrote:</span><br = style=3D"caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: = 12px; font-style: normal; font-variant-caps: normal; font-weight: = normal; letter-spacing: normal; text-align: start; text-indent: 0px; = text-transform: none; white-space: normal; word-spacing: 0px; = -webkit-text-stroke-width: 0px; text-decoration: none;" = class=3D""><blockquote type=3D"cite" style=3D"font-family: Helvetica; = font-size: 12px; font-style: normal; font-variant-caps: normal; = font-weight: normal; letter-spacing: normal; orphans: auto; text-align: = start; text-indent: 0px; text-transform: none; white-space: normal; = widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; = -webkit-text-stroke-width: 0px; text-decoration: none;" class=3D"">On = 21. 5. 19., John Nielsen wrote:<br class=3D""><blockquote type=3D"cite" = class=3D""><blockquote type=3D"cite" class=3D"">On May 17, 2021, at 2:27 = PM, Jung-uk Kim <<a href=3D"mailto:junguk.kim@gmail.com" = class=3D"">junguk.kim@gmail.com</a>> wrote:<br class=3D""><br = class=3D"">On 21. 5. 17., John Nielsen wrote:<br class=3D""><blockquote = type=3D"cite" class=3D"">I=E2=80=99m not much of a kernel programmer but = I=E2=80=99m 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.<br = class=3D""><br class=3D"">I=E2=80=99m not the original author but as the = port maintainer I am hosting the code here: <a = href=3D"https://github.com/jnielsendotnet/isboot" = class=3D"">https://github.com/jnielsendotnet/isboot</a><br class=3D""><br = class=3D"">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=E2=80=99m reading = it right (see <a = href=3D"https://github.com/jnielsendotnet/isboot/blob/master/src/ibft.h#L3= 7" = class=3D"">https://github.com/jnielsendotnet/isboot/blob/master/src/ibft.h= #L37</a> and <a = href=3D"https://github.com/jnielsendotnet/isboot/blob/master/src/ibft.c#L5= 21" = class=3D"">https://github.com/jnielsendotnet/isboot/blob/master/src/ibft.c= #L521</a>), 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 =E2=80=9CiBFT=E2=80=9D, which if it finds will be used as the = offset for reading the table. I don=E2=80=99t 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.<br class=3D""><br class=3D"">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?<br class=3D""></blockquote><br class=3D"">You may use = AcpiGetTable() and AcpiPutTable(), e.g.,<br class=3D""><br = class=3D""><span class=3D"Apple-tab-span" style=3D"white-space: pre;"> = </span>status =3D AcpiGetTable(ACPI_SIG_IBFT, =E2=80=A6);<br = class=3D""></blockquote><br class=3D"">Thank you (and Andriy) for your = responses. Good to know that ACPI_SIG_IBFT is already defined in the = upstream headers.<br class=3D""></blockquote><br class=3D"">It seems = there are two methods.<br class=3D""><br class=3D""><a = href=3D"ftp://ftp.software.ibm.com/systems/support/bladecenter/iscsi_boot_= firmware_table_v1.03.pdf" = class=3D"">ftp://ftp.software.ibm.com/systems/support/bladecenter/iscsi_bo= ot_firmware_table_v1.03.pdf</a><br class=3D""><br class=3D"">1.4.3.1 = Locating the iBFT<br class=3D""><br class=3D"">The iBFT is located by = the following methods. A platform shall implement<br class=3D"">one or = more of these methods.<br class=3D""><br class=3D"">1. The ACPI Method. = The iBFT is pointed to by an entry in the RSDT/XSDT.<br class=3D"">Note = that ACPI [ACPI=3D3.0b] specifies the string in the pointer as<br = class=3D"">=E2=80=9CIBFT=E2=80=9D (all upper case) HOWEVER the signature = in the table being pointed<br class=3D"">to is=E2=80=9CiBFT=E2=80=9D = (note the mixed case).<br class=3D""><br class=3D"">2. The Low RAM = Method. Scan for the table header signature in system<br class=3D"">memory= between 512K and 1024K. The scan MUST be done starting at<br = class=3D"">the lower address scanning forward to the higher address. = When using the<br class=3D"">Low RAM Method the table header must be = aligned on a 16-byte<br class=3D"">boundary.<br class=3D""><br = class=3D"">Note: A system operating in UEFI mode shall utilize only the = ACPI method.<br class=3D""><br class=3D"">For modern system, it seems = you should be using Method 1. I don't<br class=3D"">understand the = "HOWEVER" part, though.<br class=3D""></blockquote><br = style=3D"caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: = 12px; font-style: normal; font-variant-caps: normal; font-weight: = normal; letter-spacing: normal; text-align: start; text-indent: 0px; = text-transform: none; white-space: normal; word-spacing: 0px; = -webkit-text-stroke-width: 0px; text-decoration: none;" class=3D""><span = style=3D"caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: = 12px; font-style: normal; font-variant-caps: normal; font-weight: = normal; letter-spacing: normal; text-align: start; text-indent: 0px; = text-transform: none; white-space: normal; word-spacing: 0px; = -webkit-text-stroke-width: 0px; text-decoration: none; float: none; = display: inline !important;" class=3D"">I did little more research. = It seems iSCSI spec. predates ACPI</span><br style=3D"caret-color: = rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: = normal; font-variant-caps: normal; font-weight: normal; letter-spacing: = normal; text-align: start; text-indent: 0px; text-transform: none; = white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; = text-decoration: none;" class=3D""><span style=3D"caret-color: rgb(0, 0, = 0); font-family: Helvetica; font-size: 12px; font-style: normal; = font-variant-caps: normal; font-weight: normal; letter-spacing: normal; = text-align: start; text-indent: 0px; text-transform: none; white-space: = normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; = text-decoration: none; float: none; display: inline !important;" = class=3D"">standardization and IBM kept on using "iBFT" instead of ACPI = spec.</span><br style=3D"caret-color: rgb(0, 0, 0); font-family: = Helvetica; font-size: 12px; font-style: normal; font-variant-caps: = normal; font-weight: normal; letter-spacing: normal; text-align: start; = text-indent: 0px; text-transform: none; white-space: normal; = word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: = none;" class=3D""><span style=3D"caret-color: rgb(0, 0, 0); font-family: = Helvetica; font-size: 12px; font-style: normal; font-variant-caps: = normal; font-weight: normal; letter-spacing: normal; text-align: start; = text-indent: 0px; text-transform: none; white-space: normal; = word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: = none; float: none; display: inline !important;" class=3D"">"IBFT". = Because this confusion, some systems use "iBFT" and some = use</span><br style=3D"caret-color: rgb(0, 0, 0); font-family: = Helvetica; font-size: 12px; font-style: normal; font-variant-caps: = normal; font-weight: normal; letter-spacing: normal; text-align: start; = text-indent: 0px; text-transform: none; white-space: normal; = word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: = none;" class=3D""><span style=3D"caret-color: rgb(0, 0, 0); font-family: = Helvetica; font-size: 12px; font-style: normal; font-variant-caps: = normal; font-weight: normal; letter-spacing: normal; text-align: start; = text-indent: 0px; text-transform: none; white-space: normal; = word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: = none; float: none; display: inline !important;" class=3D"">"IBFT". = Therefore, it seems you need to test both, e.g.,</span><br = style=3D"caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: = 12px; font-style: normal; font-variant-caps: normal; font-weight: = normal; letter-spacing: normal; text-align: start; text-indent: 0px; = text-transform: none; white-space: normal; word-spacing: 0px; = -webkit-text-stroke-width: 0px; text-decoration: none;" class=3D""><br = style=3D"caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: = 12px; font-style: normal; font-variant-caps: normal; font-weight: = normal; letter-spacing: normal; text-align: start; text-indent: 0px; = text-transform: none; white-space: normal; word-spacing: 0px; = -webkit-text-stroke-width: 0px; text-decoration: none;" class=3D""><span = class=3D"Apple-tab-span" style=3D"caret-color: rgb(0, 0, 0); = font-family: Helvetica; font-size: 12px; font-style: normal; = font-variant-caps: normal; font-weight: normal; letter-spacing: normal; = text-align: start; text-indent: 0px; text-transform: none; white-space: = pre; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: = none;"> </span><span style=3D"caret-color: rgb(0, 0, 0); font-family: = Helvetica; font-size: 12px; font-style: normal; font-variant-caps: = normal; font-weight: normal; letter-spacing: normal; text-align: start; = text-indent: 0px; text-transform: none; white-space: normal; = word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: = none; float: none; display: inline !important;" class=3D"">status =3D = AcpiGetTable(ACPI_SIG_IBFT, 0, &ibft);</span><br style=3D"caret-color:= rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: = normal; font-variant-caps: normal; font-weight: normal; letter-spacing: = normal; text-align: start; text-indent: 0px; text-transform: none; = white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; = text-decoration: none;" class=3D""><span class=3D"Apple-tab-span" = style=3D"caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: = 12px; font-style: normal; font-variant-caps: normal; font-weight: = normal; letter-spacing: normal; text-align: start; text-indent: 0px; = text-transform: none; white-space: pre; word-spacing: 0px; = -webkit-text-stroke-width: 0px; text-decoration: none;"> = </span><span style=3D"caret-color: rgb(0, 0, 0); font-family: Helvetica; = font-size: 12px; font-style: normal; font-variant-caps: normal; = font-weight: normal; letter-spacing: normal; text-align: start; = text-indent: 0px; text-transform: none; white-space: normal; = word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: = none; float: none; display: inline !important;" class=3D"">if = (ACPI_FAILURE(status))</span><br style=3D"caret-color: rgb(0, 0, 0); = font-family: Helvetica; font-size: 12px; font-style: normal; = font-variant-caps: normal; font-weight: normal; letter-spacing: normal; = text-align: start; text-indent: 0px; text-transform: none; white-space: = normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; = text-decoration: none;" class=3D""><span class=3D"Apple-tab-span" = style=3D"caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: = 12px; font-style: normal; font-variant-caps: normal; font-weight: = normal; letter-spacing: normal; text-align: start; text-indent: 0px; = text-transform: none; white-space: pre; word-spacing: 0px; = -webkit-text-stroke-width: 0px; text-decoration: none;"> = </span><span class=3D"Apple-tab-span" style=3D"caret-color: rgb(0, 0, = 0); font-family: Helvetica; font-size: 12px; font-style: normal; = font-variant-caps: normal; font-weight: normal; letter-spacing: normal; = text-align: start; text-indent: 0px; text-transform: none; white-space: = pre; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: = none;"> </span><span style=3D"caret-color: rgb(0, 0, 0); font-family: = Helvetica; font-size: 12px; font-style: normal; font-variant-caps: = normal; font-weight: normal; letter-spacing: normal; text-align: start; = text-indent: 0px; text-transform: none; white-space: normal; = word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: = none; float: none; display: inline !important;" class=3D"">status =3D = AcpiGetTable("iBFT", 0, &ibft);</span><br style=3D"caret-color: = rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: = normal; font-variant-caps: normal; font-weight: normal; letter-spacing: = normal; text-align: start; text-indent: 0px; text-transform: none; = white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; = text-decoration: none;" class=3D""></div></blockquote></div><br = class=3D""><div class=3D"">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=E2=80=99m using = UEFI whether I wanted to or not. I=E2=80=99m glad that my theory that = the Low RAM Method might not work in UEFI has some merit.</div><div = class=3D""><br class=3D""></div><div class=3D"">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=E2=80=99s nice to know = what they are. I=E2=80=99ll adopt your suggested approach.</div><div = class=3D""><br class=3D""></div><div class=3D"">JN</div><div = class=3D""><br class=3D""></div></body></html>= --Apple-Mail=_CA23D759-B102-45E6-AA8F-5B26F2CA9D0F--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?291E1068-2F9A-4C6B-B7F7-D47B112A2BE5>