setting Beagle Bone pinmux directly

Since I can’t get the devicetree working on the 4.4.62 kernel, I’m trying to set the GPIO pin configuration directly. I did this on the Beagle Board a long time ago, and am trying to adapt that code.

So, I have this code :

int fd = open("/dev/mem", O_RDWR | O_SYNC);
volatile ulong pinmux;
pinmux = (ulong
) mmap(NULL, 0x2000, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0x44E10000);
if (pinmux == MAP_FAILED) {
printf(“Pinmux Mapping failed\n”);
pinmux[0x0880/4] = 0x0f; // P8.25 GPIO1.0 write, no pulls, mode 7
pinmux[0x0884/4] = 0x0f; // P8.24 GPIO1.1 write, no pulls, mode 7

and then try to write values to the set and clear registers :
fd = open("/dev/mem", O_RDWR | O_SYNC);

// GPIO Configuration: configure are input
volatile ushort gpios;
gpios = (ushort
) mmap(NULL, 0x2000, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0x4804C000);
if (gpios == MAP_FAILED) {
printf(“Gpios Mapping failed\n”);
gpios[gpios_clear] = 0xff;
gpios[gpios_set] = j;

But I don’t see any response. More oddly, I don’t see any change in

Which lists the above pins as :
pin 32 (44e10880.0) 00000032 pinctrl-single
pin 33 (44e10884.0) 00000032 pinctrl-single

I think I am writing 0x0f to those registers, and I still see 0x32, which would indicate why the GPIOs are not getting through to the header pins.
If I read out the pinmux register in my program, it ALSO shows as 0x32, so apparently the write to that register is silently ignored.

Has anybody done this and know where I’m going wrong?

Thanks much,


  • active_low I believe is how you set your pin high / low logic. e.g. what state it is in by default(reverse logic, or not).
  • direction is the file you need to change in order to set the pin as input or output. values are limited to “in” or “out” I believe.
  • edge is the file you set low to high or high to low edge detect in. I do not remember all the values, but I think there are three one of which can be “both”. Setting this file is required if you want to use any pin “event” monitoring.
  • value is the file you set high, or low for high, or low pin state. In the case of input, you can not change this file, but you can read from it. Valid values are 0, and 1 for output pins. Input are the same except of course you can not set the pin value, only read it.

I’ve tried this, too, and am not having much success with it. I may be trying to use GPIOs that are reserved. I will try it with a couple more pins and see if I can get anywhere.



OK, GPIOs 45 to 47 are available and work. So, far, none of the other GPIOs I’ve tried work, as they seem to be assigned to other mode selections. The export and direction files don’t seem to change the pinmux setting.

Is there some utility that can change the pinmux assignment, so I can set those pins to Mode 7?
Funny that GPIOs 45-47 don’t show up as in mode 7 in /sys/kernel/debug/pinctrl/44e10800.pinmux
I don’t understand how they can work if not in Mode 7. Well, this is still all confusing.



Charles Steinkuehler says the new kernels use memory management to lock access to the pinmux registers. This certainly matches the symptoms I am getting. Hopefully, he can tell me how to use config-pin to set it up.


First, you disable universal IO, second, if you do not need hdmi, you disable hdmi video, and audio at boot. Through /boot.uEnv.txt. This will free up any pin that’s not related to I2C-0, I2C-2, the eMMC, and possibly a few others I’m not thinking of off the top of my head.

That’s /boot/uEnv.txt, typo above.

The kernel is doing what a kernel does, manager of the resources!
Try this in a terminal:

config-pin -h

Here’s an example usage:

config-pin P9.14 low_pd

That set header pin P9.14 to a GPIO direction output and set to LOW and with pull-down resistor.
It works great!

Use this extremely useful spreadsheet for reference:

The file is pinmux.ods.