Re­cently, feel­ing re­stric­ted by the hard­ware on my laptop, I built my­self a desktop com­puter based on a re­cently re­leased Ryzen CPUs by AMD. These CPUs are built on a new ar­chi­tec­ture, plug into a new sort of socket and have a whole new eco­sys­tem around them.

Mother­board was one of the most dif­fi­cult things to de­cide on. I wanted to go for a small sys­tem, but one, that’s large enough for fu­ture ex­pan­sion into wa­ter cool­ing. This meant go­ing for a smal­ler form factor mother­board – µATX of, even bet­ter, mITX. Alas, nobody had re­leased any mother­boards of mITX form factor by the time, so µATX was the only choice.

After some re­search I de­cided on the MSI B350M MOR­TAR ARC­TIC mother­board, be­cause it had a pretty nice fea­ture set (S/P­DIF, sens­ible num­ber of USB ports, RGB head­er) and matched the col­our scheme of my white build as well!

Trouble did­n’t take long at all to rear its head. Turns out the mother­board uses a pro­pri­et­ary Su­per I/O chip: Nu­vo­ton NC­T6795D! This chip is known to be re­spons­ible for little, but im­port­ant, de­tails such as mon­it­or­ing tem­per­at­ures around the board, con­trolling the speed of fans and so on. This chip is ap­par­ently made ex­clus­ively for MSI and MSI re­fuses to provide the spec­sheets for the chip:

me: Ad­di­tion­ally, please re­lease/­give me the spec­sheet for NC­T6795D chip.

MSI: We are sorry that we can­not sup­ply the de­tails spec of it, Or you can con­tact the chip­set vendor dir­ectly.Thanks!

me: What about the RGB head­er? Nu­vo­ton is on re­cord say­ing that we should re­quest the spec­sheets from you as it is a chip de­signed spe­cific­ally for MSI. Can you please com­mu­nic­ate with Nu­vo­ton and make sure the sheets are re­leased?

MSI: We are sorry that we can­not sup­ply the de­tails spec of it. Sorry for any in­con­veni­ence caused you.

me: pretty please?

MSI: We are sorry that the de­tailed data­sheet is re­lated with con­fid­en­tial of MSI and the Man­u­fac­turer. It can­not be made pub­lic due to con­fid­en­ti­al­ity agree­ment. Sorry for the in­con­veni­ence caused you.

That’s a shame, but this ex­change was by no means a worth­less one. Even if in­dir­ectly, it points out where the RGB header is con­trolled. I de­cided to fol­low this lead.

Be­ing a stu­dent, I get to claim one of those free everything Mi­crosoft li­censes free of charge. Hav­ing in­stalled the Win­dows 10, MSI’s Gam­ing App (the pro­gram which al­lows con­trol of the RGB head­er) and a copy of RWEverything1 I start dig­ging around. Shortly after I’m greeted by great news: chan­ging the col­our in the Gam­ing App would also make the bot­tom two rows change sig­ni­fic­antly as well!

RWEverything re­act­ing to col­our changes with the Gam­ing App

The next day, as I was col­lect­ing the in­form­a­tion about what each bit in the sI/O re­gisters does, I no­ticed the re­gisters not ac­tu­ally chan­ging the col­our un­less the Gam­ing App was turned on first. Wor­ried about hit­ting a dead end, I star­ted look­ing into dis­as­sem­blers and de­bug­gers on Win­dows. The ob­vi­ous first op­tion was MS­VC. Dis­ap­point­ingly, I could­n’t make to work in the end – its de­bug­ger re­fused to show me the dis­as­sembly no mat­ter what. I ended up set­tling on x64dbg, a very awe­some visual de­bug­ger­/dis­as­sem­bler.

Pick­ing at the dis­as­sembly of MSI_LED.exe even­tu­ally led me to two in­ter­est­ing func­tions: IoPortWriteByte and DeviceIoControl, which the former func­tion calls. Noth­ing, that would look like ac­tual writ­ing to an I/O Port, though. I sel­dom do any­thing with Win­dows and this is my first time look­ing into Win­dows’ in­tern­als too. That’s the reason why it took me till Sat­urday to real­ise that the ac­tual com­mu­nic­a­tion hap­pens in­side a driver of some sort, not the ex­ecut­able I was look­ing at.

Could I de­bug a driver in a live sys­tem? Turns out it is pos­sible, but not without a second com­puter with a serial head­er. Not only I haven’t an­other com­puter, I do not have a cable that could do serial either. In the end, I ended up dis­as­sembling the driver it­self, learn­ing the Win­dows driver ba­sics as I went. Know­ing noth­ing about Win­dows drivers meant stum­bling around and fig­ur­ing what all the as­sembly did. Luck­ily, the driver was only 4KiB in size, so by the even­ing I had a nice trace of the in and out in­struc­tions that the Gam­ing App in­dir­ectly in­vokes:


Boot back into Linux-land, open("/dev/port", "wb"), re­peat all the same calls… to my de­light – the col­our changes! Hoo­ray!

There are some out­stand­ing ques­tions, such as: “Why did­n’t, then, writ­ing straight sI/O re­gister via RWEverything work?” I don’t know. It might be the un­usual se­quence of 87 87 07 12 that ap­pears be­fore every write in the dumps2. I’m glad it all works, and am not go­ing to risk brick­ing my board a second time.

All this is im­ple­men­ted in a util­ity tool called msi-rgb. In the end this util­ity tool ended up be­ing much more flex­ible com­pared to the MSI’s own app. While msi-rgb does not mon­itor the CPU tem­per­at­ure or re­act to the mu­sic, it al­lows for much more cus­tom­isa­tion than the 7 static col­ours offered by the Win­dows app. I haven’t yet in­vest­ig­ated mak­ing the util­ity more port­able, but it should­n’t be too hard see­ing the only really un­port­able part in it is the use of /dev/port device.

  1. Now this is an awe­some util­ity. If not for it, I would prob­ably have given up.↩︎

  2. Di­ver­ging from the dump some­what, do­ing just 87 07 12 works just fine as well. A de­tail, but an in­ter­est­ing one nev­er­the­less.↩︎