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:
- Download the exact version of your current BIOS from the GIGABYTE website
- Use UEFITool and IFR Extractor LS to find the byte offset of the RGB values for your particular BIOS
- 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.
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.
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.
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