.. | .. |
---|
42 | 42 | supported for request_firmware_into_buf(). |
---|
43 | 43 | |
---|
44 | 44 | * Firmware is not accessible through typical means: |
---|
| 45 | + |
---|
45 | 46 | * It cannot be installed into the root filesystem |
---|
46 | 47 | * The firmware provides very unique device specific data tailored for |
---|
47 | 48 | the unit gathered with local information. An example is calibration |
---|
.. | .. |
---|
202 | 203 | |
---|
203 | 204 | If you echo 0 into it means MAX_JIFFY_OFFSET will be used. The data type |
---|
204 | 205 | for the timeout is an int. |
---|
| 206 | + |
---|
| 207 | +EFI embedded firmware fallback mechanism |
---|
| 208 | +======================================== |
---|
| 209 | + |
---|
| 210 | +On some devices the system's EFI code / ROM may contain an embedded copy |
---|
| 211 | +of firmware for some of the system's integrated peripheral devices and |
---|
| 212 | +the peripheral's Linux device-driver needs to access this firmware. |
---|
| 213 | + |
---|
| 214 | +Device drivers which need such firmware can use the |
---|
| 215 | +firmware_request_platform() function for this, note that this is a |
---|
| 216 | +separate fallback mechanism from the other fallback mechanisms and |
---|
| 217 | +this does not use the sysfs interface. |
---|
| 218 | + |
---|
| 219 | +A device driver which needs this can describe the firmware it needs |
---|
| 220 | +using an efi_embedded_fw_desc struct: |
---|
| 221 | + |
---|
| 222 | +.. kernel-doc:: include/linux/efi_embedded_fw.h |
---|
| 223 | + :functions: efi_embedded_fw_desc |
---|
| 224 | + |
---|
| 225 | +The EFI embedded-fw code works by scanning all EFI_BOOT_SERVICES_CODE memory |
---|
| 226 | +segments for an eight byte sequence matching prefix; if the prefix is found it |
---|
| 227 | +then does a sha256 over length bytes and if that matches makes a copy of length |
---|
| 228 | +bytes and adds that to its list with found firmwares. |
---|
| 229 | + |
---|
| 230 | +To avoid doing this somewhat expensive scan on all systems, dmi matching is |
---|
| 231 | +used. Drivers are expected to export a dmi_system_id array, with each entries' |
---|
| 232 | +driver_data pointing to an efi_embedded_fw_desc. |
---|
| 233 | + |
---|
| 234 | +To register this array with the efi-embedded-fw code, a driver needs to: |
---|
| 235 | + |
---|
| 236 | +1. Always be builtin to the kernel or store the dmi_system_id array in a |
---|
| 237 | + separate object file which always gets builtin. |
---|
| 238 | + |
---|
| 239 | +2. Add an extern declaration for the dmi_system_id array to |
---|
| 240 | + include/linux/efi_embedded_fw.h. |
---|
| 241 | + |
---|
| 242 | +3. Add the dmi_system_id array to the embedded_fw_table in |
---|
| 243 | + drivers/firmware/efi/embedded-firmware.c wrapped in a #ifdef testing that |
---|
| 244 | + the driver is being builtin. |
---|
| 245 | + |
---|
| 246 | +4. Add "select EFI_EMBEDDED_FIRMWARE if EFI_STUB" to its Kconfig entry. |
---|
| 247 | + |
---|
| 248 | +The firmware_request_platform() function will always first try to load firmware |
---|
| 249 | +with the specified name directly from the disk, so the EFI embedded-fw can |
---|
| 250 | +always be overridden by placing a file under /lib/firmware. |
---|
| 251 | + |
---|
| 252 | +Note that: |
---|
| 253 | + |
---|
| 254 | +1. The code scanning for EFI embedded-firmware runs near the end |
---|
| 255 | + of start_kernel(), just before calling rest_init(). For normal drivers and |
---|
| 256 | + subsystems using subsys_initcall() to register themselves this does not |
---|
| 257 | + matter. This means that code running earlier cannot use EFI |
---|
| 258 | + embedded-firmware. |
---|
| 259 | + |
---|
| 260 | +2. At the moment the EFI embedded-fw code assumes that firmwares always start at |
---|
| 261 | + an offset which is a multiple of 8 bytes, if this is not true for your case |
---|
| 262 | + send in a patch to fix this. |
---|
| 263 | + |
---|
| 264 | +3. At the moment the EFI embedded-fw code only works on x86 because other archs |
---|
| 265 | + free EFI_BOOT_SERVICES_CODE before the EFI embedded-fw code gets a chance to |
---|
| 266 | + scan it. |
---|
| 267 | + |
---|
| 268 | +4. The current brute-force scanning of EFI_BOOT_SERVICES_CODE is an ad-hoc |
---|
| 269 | + brute-force solution. There has been discussion to use the UEFI Platform |
---|
| 270 | + Initialization (PI) spec's Firmware Volume protocol. This has been rejected |
---|
| 271 | + because the FV Protocol relies on *internal* interfaces of the PI spec, and: |
---|
| 272 | + 1. The PI spec does not define peripheral firmware at all |
---|
| 273 | + 2. The internal interfaces of the PI spec do not guarantee any backward |
---|
| 274 | + compatibility. Any implementation details in FV may be subject to change, |
---|
| 275 | + and may vary system to system. Supporting the FV Protocol would be |
---|
| 276 | + difficult as it is purposely ambiguous. |
---|
| 277 | + |
---|
| 278 | +Example how to check for and extract embedded firmware |
---|
| 279 | +------------------------------------------------------ |
---|
| 280 | + |
---|
| 281 | +To check for, for example Silead touchscreen controller embedded firmware, |
---|
| 282 | +do the following: |
---|
| 283 | + |
---|
| 284 | +1. Boot the system with efi=debug on the kernel commandline |
---|
| 285 | + |
---|
| 286 | +2. cp /sys/kernel/debug/efi/boot_services_code? to your home dir |
---|
| 287 | + |
---|
| 288 | +3. Open the boot_services_code? files in a hex-editor, search for the |
---|
| 289 | + magic prefix for Silead firmware: F0 00 00 00 02 00 00 00, this gives you |
---|
| 290 | + the beginning address of the firmware inside the boot_services_code? file. |
---|
| 291 | + |
---|
| 292 | +4. The firmware has a specific pattern, it starts with a 8 byte page-address, |
---|
| 293 | + typically F0 00 00 00 02 00 00 00 for the first page followed by 32-bit |
---|
| 294 | + word-address + 32-bit value pairs. With the word-address incrementing 4 |
---|
| 295 | + bytes (1 word) for each pair until a page is complete. A complete page is |
---|
| 296 | + followed by a new page-address, followed by more word + value pairs. This |
---|
| 297 | + leads to a very distinct pattern. Scroll down until this pattern stops, |
---|
| 298 | + this gives you the end of the firmware inside the boot_services_code? file. |
---|
| 299 | + |
---|
| 300 | +5. "dd if=boot_services_code? of=firmware bs=1 skip=<begin-addr> count=<len>" |
---|
| 301 | + will extract the firmware for you. Inspect the firmware file in a |
---|
| 302 | + hexeditor to make sure you got the dd parameters correct. |
---|
| 303 | + |
---|
| 304 | +6. Copy it to /lib/firmware under the expected name to test it. |
---|
| 305 | + |
---|
| 306 | +7. If the extracted firmware works, you can use the found info to fill an |
---|
| 307 | + efi_embedded_fw_desc struct to describe it, run "sha256sum firmware" |
---|
| 308 | + to get the sha256sum to put in the sha256 field. |
---|