Skip site navigation (1)Skip section navigation (2)
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 &lt;<a =
href=3D"mailto:jkim@freebsd.org" class=3D"">jkim@freebsd.org</a>&gt; =
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 &lt;<a href=3D"mailto:junguk.kim@gmail.com" =
class=3D"">junguk.kim@gmail.com</a>&gt; 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. &nbsp;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. =
&nbsp;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". =
&nbsp;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". =
&nbsp;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, &amp;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, &amp;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>