Thursday, June 4, 2015

Uitlity: Reading and Writing PCI, IO and memory with Linux Firmware Debug Kit (lfdk) in Linux

Many BIOS engineers are familiar with ru.exe in DOS and R/W everything in Windows.  One frequently asked question is whether there is an equivalent utility in Linux.  The answer is "sort of".

Linux Firmware Debug Kit (lfdk) provides read/write functions to PCI[1], IO and memory spaces.

lfdk's deb package is available but it is outdated. I usually download [3] and compile source code, and run ldfk manually in a terminal (ctrl + alt + T if you are running Ubuntu +Unity) as below:

  1. sudo apt-get install -f git libncurses-dev
  2. git clone
  3. cd lfdk
  4. make
  5. cd bin
  6. sudo insmod ./lfdd_drv.ko
  7. sudo ./lfdk

A familiar screen will pop up

The navigation  is to use arrow keys and hotkeys L, M and I to different spaces as instructed on the bottom of the lfdk.

[1] Built-in lspci command can be used to read PCI configuration space, too
[2] This is tested in Ubuntu Linux 12.04 to 15.04.
[3] One can also download the source code from above.

Monday, November 11, 2013

[Presentation] BIOS, Linux and Firmware Test Suite in-between

I was invited to present "BIOS, Linux and Firmware Test Suite in-between" in Debian Taiwan's MiniDeb Conf in Taipei, Taiwan on Nov 9, 2013. The presentation is shared @ slideshare and can be viewed below:

Firmware Test Suite is an ongoing project that targets to automate firmware and hardware related tests. It receives some attentions from various parties including hardware, software and system vendors. (I also presented the similar topic in UEFI Plugfest in Sept, 2013, and the presentation slides are available @

Friday, August 30, 2013

Info Session: Improving BIOS Compatibility on Linux

I had a chance to present a BIOS-related topic "Improving BIOS Compatibility on Linux" in workplace, and the presentation is publicly available. Hope it may interest someone. :-)

Tuesday, July 2, 2013

ACPI AC Adapter (2) - How does Linux handle it?

ACPI AC Adapter Implementation in Linux Kernel

ACPI AC Adapter (1) introduced the theory of interfaces between BIOS and an OS, but a real example is always more convincing than anything else.

SysFs Node

In Linux, one can find out whether a laptop PC has AC plugged in by "cat /sys/class/power_supply/online". Linux ACPI AC driver evaluates _PSR and returns 1 for "AC is online" and 0 for "AC is offline". The sysfs node is also used by user-space applications.

Supported Objects

Surprisingly (or not), not all control methods defined in ACPI AC are supported. In fact, only _PSR is evaluated in Linux ACPI AC driver.

As ACPI covers very broad and rich features, kernel developers may find some of them "uninteresting". For example. _PSR is required, in software's perspective, to know whether AC is online, but which parts of a system is powered (i.e. _PCL) may not be that useful for laptop PCs (which AC usually powers everything). In some other cases, few BIOS implements _PIF and there is hardly any reason that someone decides to add _PIF supports to Linux.

AC Events

It is very interesting to see how an driver responds to ACPI events. In the above source code it is obvious that the driver behaves the same for all events equals 0x80, 0x00, 0x01. It also responds the same to all other ACPI events with an additional error message.

For example, it was seen that some BIOSes issue Notify(AC, 0x81) when AC adapter is plugged or plugged. Apparently Linux kernel does not think 0x81 is a valid event (nor can I find any 0x81 for AC in ACPI); however, Linux still behaves as well with Notify(AC, 0x80).

Suspend and Resume

Another interesting part in ACPI AC driver is acpi_ac_resume called when a system resumes from suspend or hiberation. It compares the "before" and "after" _PSR and issues an uEvent if they are different. This implies BIOSes need not to issue a Notify(AC, 0x80) during waking up to save some CPU cycles; however, this may be specific to Linux. As there is no rule in ACPI spec, one may want to verify the behaviors of the target OSes (ex. Windows).


Linux kernel source code (3.10): ACPI AC adpater driver in drivers/acpi/ac.c

Sunday, June 23, 2013

ACPI AC Adapter (1) - Introduction

In ACPI Control Method Battery (2), we see how ACPI's definition for control method battery and read the data in Ubuntu Linux. However, battery does not usually go alone - ACPI AC Adapter always goes with it.

AC Adapter Interface

Unlike the complexity of a control method battery, AC adapter is much simpler and three objects are mandatory:
  • _HID (Hardware ID) - needs to be ACPI0003
  • _PSR (Power Source) - indicates whether AC is online
  • _PCL(1) (Power Consumer List) - refers what is powered by AC

Below is a sample for AC adapter that returns whether AC is online from an EC register in _PSR:

Plugging and Unplugging AC Adapter

When AC adapter is plugged or unplugged, BIOS needs to issue a notification event as the example:

It is worth noting that only 0x80 is needed. Some BIOS will also issue Notify(_SB.AC, 0x81) that is not only redundant but also incorrect. Some BIOS also issues Notify(_SB.BAT, 0x80) and Notify(_SB.BAT, 0x81). While OS is smart enough to know that battery status is also changed, one may argument that issuing notification to battery is correct and at least won't break anything.

In my opinions, it is not incorrect to issue Notify(_SB.BAT, 0x80) as Battery State in _BST is definitely changed to discharging, assuming only one AC source and one battery are present in a system; however, issuing Notify(_SB.BAT, 0x81) and asking OS to re-enumerate _BIF/_BIX is only a waste of CPU cycles.

What is ACPI AC Adapter Affecting?

It is definitely not surprising to know the little AC icon in OS's taskbar uses the return value of AC._PSR - that's  the only way that an OS knows whether a system is powered by an AC adapter. But... what else?

It is true that hardware state is different from powered-by-AC to powered-by-battery - at least from the viewpoint of the power circuit; however, this is only small part of the system board and we often see much more difference and affecting the system. When a system is powered by AC source, it is, in most cases, running at performance mode - CPU can spend more time in maximum frequency, power-saving features are less aggressive, fan runs at higher speed, and the panel may be brighter. All of these can be changed when OS finds out AC is offline from AC._PSR.

The implication? If one sees stability issues without AC only, playing around _PSR may help identify whether it is the power circuit or is an OS beahviours, i.e. one device and its driver are too aggressive with its power-saving features. One way to distinguish whether it is always reports 1 in _PSR - if the problem persists, it is the power circuit (hardware) that causes the problem. I have seem a number of times that bad-quality power components that hang the system and many other times that a device or its driver failed the system. This technique always helps a quick and good direction to real problems.


How does Linux kernel handle ACPI AC adapter?


  1. It seems _PCL is defined but is not used in Linux kernel.


  • ACPI Specification 5.0 - Sec. 10.3
  • ACPI Specification 5.0 - Table 5-121
  • Linux kernel source code (3.10)

Thursday, June 20, 2013

ACPI Brightness Control (4) - Workaround for Brightness Problems in Ubuntu Linux

This blog discusses some common errors for brightness control and hotkeys. It will be updated from time to time.

Initial Zero Brightness

Some system BIOS reports zero in _BQC at boot-up, and it causes Linux kernel to dim the screen to minimum. In some cases, the panel is completely black out. This is because Linux's ACPI VGA driver does the following when it starts:

  1. Read _BQC for current brightness level
  2. Set brightness level to maximum - it is to verify whether brightness work
  3. Restore brightness level from 1
Aside from getting BIOS fixes which is usually close to impossible as the product is shipped (but I do encourage people to call customer services to complain!), there are three ways to fix it:

Kernel parameter

Edit /etc/default/grub
Add "video.use_bios_initl_backlight=0" to GRUB_CMDLINE_LINUX_DEFAULT
Run "sudo update-grub"

Bootup script

Edit the file /etc/rc.local
Add a line "echo 4 > /sys/class/backlight/acpi_video0/brightness" before "exit 0"

Quirk to acpi/video.c

If you are familiar with Linux kernel, you can develop a patch as in If not, it is more than welcomed to file a bug like LP#1184501, run "sudo dmidecode > dmi.log", attach dmi.log and assign the bug to me. I am very happy to develop a patch for it, and you may help many others using Linux!

Brightness Fails to Work

If you are have laptop PC that BIOS fails to adjust brightness via acpi_video, you can try add the kernel parameter "acpi_backlight=vendor".

What the parameter does is to stop using acpi video to adjust the brightness - also skips creating sysfs nodes for acpi_videoX. As a result, a desktop daemon (like GSD) will find other brightness sysfs nodes created by other drivers, such as Intel_backlight, thinkpad_backlight and so on.

A Hotkey Press Changes Two Levels

In Figure 2 of ACPI Brightness Control (3) - Hotkeys in Ubuntu Linux, a solid and a dash line were draw to call to BIOS _BCM. This implies a hotkey can and may change a brightness twice. This is the case with Gnome-Setting-Daemon in Ubuntu.

If seeing this problem, one can add an kernel parameter to workaround it:
  • sudo vi /etc/default/grub
  • add brightness_switch_enabled=N to GRUB_CMDLINE_LINUX_DEFAULT
  • sudo update-grub
  • reboot

This will skip the dashed line call in ACPI Video driver:



ACPI Brightness Control (3) - Hotkeys in Ubuntu Linux

In ACPI Brightness Control (1) - Control Methods and ACPI Brightness Control (2) - Hotkeys, we understand how ACPI designs brightness from BIOS's perspectives. In this blog, we will see them in action using Ubuntu as an example.

Brightness Sysfs Nodes in Linux Kernel

When booting up, Linux's ACPI VGA driver (drivers/acpi/video.c) enumerates ACPI AML (DSDT and SSDT) to look for output devices that support brightness control. Once identified, it creates sysfs nodes in /sys/class/backlight/acpi_video0. If more than one output device is found, it creates acpi_video1 and so on.

FIgure 1 - Sysfs Nodes for Brightness
Figure 1 shows files in acpi_video0 directory. Three files are particularly important:

  • actual_brightness - implements _BQC
  • brightness - implements _BCM, and also record current brightness level
  • max_brightness - implements _BCL and converts it to number of levels
For example, the _BCL in this Thinkpad reports 16 brightness levels with Ubuntu 12.04, and therefore "cat max_brightness" returns 15. Current brightness can be read by executing "cat actual_brightness" or "cat brightness". In most cases, both max_brightness and brightness return the same value (this should not be surprising) - they are only different if something breaks in kernel or BIOS - such as _BQC does not change with _BCM.

To change brightness level, one writes a value to brightness, ranged from 0 to max_brightness. In this system, it is from 0 to 15. ACPI VGA driver will convert it to the actual value in _BCL and write to _BCM. 

Hotkey Implementation in Ubuntu Linux

Figure 2 - Overall Process for Brightness Hotkeys
Figure 2 is an expansion of ACPI Brightness Control (2) - Hotkeys. It shows that many tasks are done even with a single hotkey press, and it also shows separation between OS and BIOS is clear - the clean interface makes hotkey development easy and that's exactly what ACPI is for. Let's add more details to OS level as it is in Figure 3.

Figure 3 - Brightness and Desktop Daemon
Ubuntu ships with gnome-setting-daemon (GSD) that listens to keycode events. ACPI VGA driver converts ACPI notification events to keycodes, and GSD changes brightness via sysfs nodes according. GSD is also responsible for reading brightness levels from sysfs nodes to show OSD for users and to create slider for changing brightness. It is also worthy noting that ACPI VGA driver can also calls _BCM to change brightness without interacting with GSD, but no OSD may be shown.

As GSD is designed to listen to keycode, System vendor may design BIOS to generate other none-standard ACPI events, such as WMI events, as long as there is a kernel driver to do the conversion; however, this is not a suggested.

PS. Please note keycodes are not the same as KBC's scancode.

Debugging Brightness (Hotkey) Failures

From Figure 3, it becomes obvious brightness hotkeys can fail for two primary reasons:
  1. BIOS does not generate events
  2. _BCM fails to change brightness
In Linux, it is easy to verify whether ACPI VGA events and keycodes are generated:
  • Run "acpi_listen" to show ACPI standard events
  • Run "sudo showkey" to show keycodes
One can trigger writes to _BCM as in "Brightness Sysfs Nodes in Linux Kernel", if brightness is changed but LCD panel is not, BIOS did not implement _BCM correctly (or graphics drivers do not respond requests from BIOS in some cases).