I persistently changed the RGB colors of my GIGABYTE motherboard using EFI variables

Neither GIGABYTE’s official RGB Fusion software nor the excellent OpenRGB support changing the RGB colors of recent GIGABYTE boards in a way that persists reboots. However there is a way to do this that involves some slightly scary editing of EFI variables and the danger of bricking your board if you’re not careful.

GIGABYTE’s RGB Fusion application is notoriously bad. And while older boards had an option called RGB Fusion in the BIOS they removed this on recent boards—semingly in an attempt to force users to intall their crappy desktop app. Though before you head off immediately to install GIGABYTE’s bloatware, let me tell you that you probably want OpenRGB instead. If you’re unfamiliar, OpenRGB aspires to control all your RGB peripherals so you don’t need to install crapware from 11 different vendors on your machine. Plus its lightweight and works on Linux. And although OpenRGB has save-to-device functionality for some devices, it doesn’t support this for GIGABYTE mainboards.

Using OpenRGB meant that my case fans were lighting up in blazing GIGABYTE orange™ each time I powered up my machine until OpenRGB started. This was bugging me quite a bit until one day I stumbled upon this magnificent article by a guy called Rich—thanks Rich. His article basically has the solution I’m about to present here but he provides an offset into an opaque byte array that you’ll need that only works for an outdated BIOS version of his specific mainboard. I’m going to rectify this and show you how to work out this offset for your own board. I haven’t found a good writeup bringing all the bits and pieces you need to pull this off together in one place so I’m aiming to do that here.

Remember the RGB Fusion BIOS option I mentioned before? The option is no longer present on newer boards but the underlying foundations are still there. The BIOS stores its current configuration in an EFI variable called Setup which is a big opaque byte array. And if you know the right offset into the byte array you can simply change the three bytes which determine the RGB values of your motherboard. But if you change the wrong bytes all kinds of things can happen—ostensibly you can even brick your board. So the general outline of steps is as follows:

  1. Download the exact version of your current BIOS from the GIGABYTE website
  2. Use UEFITool and IFR Extractor LS to find the byte offset of the RGB values for your particular BIOS
  3. Boot a USB flash drive with grub-mod-setup_var and change the values at the particular byte offset

Downloading the BIOS

Boot into your BIOS and note down the name of your motherboard and BIOS version. Then head to your motherboard’s page on the GIGABYTE website and download the correct BIOS version. Unzip the archive—the file of interest is several MBs large and named after your motherboard model.

Finding the byte offset

You’ll need UEFITool and IFR Extractor LS. The latter has an end-of-life notice on its GitHub page because they rewrote the thing in Rust. I’ve still used the old version because that’s what I’ve seen other people use. If you’re on Arch like me you’re in luck because both of them are in the AUR.

Screenshot of the UEFITool search dialog

Run UEFITool and go to File → Open image file and open the file named after your motherboard model from earlier. You should see an expandable tree structure with some entries having readable names and others having UUIDs as names. Go to Action → Search, switch to the Text tab and search for “RGB Fusion” while making sure that Header and body is checked. There should be multiple matches in an entry named Setup/P32. Double click a search result to jump to the entry. Right click the Setup/P32 entry and select Extract as is to write it to a file.

Screenshot of UEFITOOL

Now use the previously installed IFR Extractor LS to convert the file to a readable format.

ifrextract Section_PE32_image_Setup_Setup.sct readable.txt

Search for “RGB Fusion” in the text file. For my BIOS version the relevant section looks like this:

0x2DAB2     Form: RGB Fusion, FormId: 0x2944 {01 86 44 29 E5 0B}
0x2DAB8         Suppress If {0A 82}
0x2DABA             QuestionId: 0x1A7 equals value 0x0 {12 06 A7 01 00 00}
0x2DAC0             Gray Out If {19 82}
0x2DAC2                 QuestionId: 0x26F equals value 0x1 {12 06 6F 02 01 00}
0x2DAC8                 Numeric: LED Hue, VarStoreInfo (VarOffset/VarName): 0x26C, VarStore: 0x1, QuestionId: 0x1A6, Size: 4, Min: 0x0, Max 0xFFFFFF, Step: 0x1 {07 9A F7 0B F8 0B A6 01 01 00 6C 02 10 22 00 00 00 00 FF FF FF 00 01 00 00 00}
0x2DAE2                     Default: DefaultId: 0x0, Value (32 bit): 0xFF2100 {5B 09 00 00 02 00 21 FF 00}
0x2DAEB                 End {29 02}
0x2DAED             End If {29 02}
0x2DAEF         End If {29 02}
0x2DAF1         Gray Out If {19 82}
0x2DAF3             QuestionId: 0x26F equals value 0x1 {12 06 6F 02 01 00}
0x2DAF9             One Of: RGB Fusion, VarStoreInfo (VarOffset/VarName): 0x26B, VarStore: 0x1, QuestionId: 0x1A7, Size: 1, Min: 0x0, Max 0x6, Step: 0x0 {05 91 E5 0B E6 0B A7 01 01 00 6B 02 10 10 00 06 00}
0x2DB0A                 Default: DefaultId: 0x0, Value (8 bit): 0x3 {5B 06 00 00 00 03}
0x2DB10                 One Of Option: Off, Value (8 bit): 0x0 {09 07 E7 0B 00 00 00}
0x2DB17                 One Of Option: Pulse Mode, Value (8 bit): 0x1 {09 07 EB 0B 00 00 01}
0x2DB1E                 One Of Option: Color Cycle, Value (8 bit): 0x2 {09 07 FE 0B 00 00 02}
0x2DB25                 One Of Option: Static Mode, Value (8 bit): 0x3 (default MFG) {09 07 FD 0B 20 00 03}
0x2DB2C                 One Of Option: Flash Mode, Value (8 bit): 0x4 {09 07 FF 0B 00 00 04}
0x2DB33                 One Of Option: Double Flash, Value (8 bit): 0x5 {09 07 00 0C 00 00 05}
0x2DB3A                 One Of Option: Demo Mode, Value (8 bit): 0x6 {09 07 0E 0C 00 00 06}
0x2DB41             End One Of {29 02}
0x2DB43         End If {29 02}
0x2DB45     End Form {29 02}

And voilà! The byte offsets are the numbers after VarStoreInfo (VarOffset/VarName): and VarStore: 0x1 refers to the Setup EFI variable. For my BIOS the mode is stored at offset 0x26B and the value 0x3 indicates a static color which is what I want. The blue value is stored at offset 0x26C and the green and red values are stored in the subsequent bytes (yes, the order is BGR).

Changing the RGB values

Now all that is left is to actually write to the particular byte offsets in the Setup EFI variable. To do this I’ve used grub-mod-setup_var. They have a deprecation notice on their GitHub page because they rewrote the project in Rust—notice a trend?—but I’ve still used the old project because this is what Rich used in his aforementioned blog post.

Photo of my computer case after the RGB color change

Grab the latest release from their GitHub page and format a USB flash drive with a bootable EFI partition. Move the EFI file to /EFI/boot/bootx64.efi on the EFI partition so it will be recognized. Then boot from the flash drive and you will be dropped into a CLI. Before writing anything you should check that the values stored at the byte offsets of interest are what one would expect. If you haven’t changed those values before, the mode should be 0x3 and the BGR values should be 0x0, 0x21 and 0xFF—namely GIGABYTE orange™. The commands will output a lot of text but you will find the values somewhere in there. Be sure to change the byte offsets to suit your board.

grub> setup_var_3 0x26B
grub> setup_var_3 0x26C
grub> setup_var_3 0x26D
grub> setup_var_3 0x26E

And finally you can set your desired colors which should take effect right after the reboot. I went for a pretty magenta.

grub> setup_var_3 0x26C 0xFF
grub> setup_var_3 0x26D 0x00
grub> setup_var_3 0x26E 0xFF
grub> reboot

Go to the front page