SkillAgentSearch skills...

Uiomem

uiomem is a Linux device driver for accessing a memory area outside the Linux Kernel management from user space.

Install / Use

/learn @ikwzm/Uiomem
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

uiomem(User space mappable I/O Memory)

This project is under development.

See the develop branch for this project for details.

https://github.com/ikwzm/uiomem/tree/develop

Currently 1.1.0-beta.1 is tentatively released.

https://github.com/ikwzm/uiomem/tree/v1.1.0-beta.1.

Overview

Introduction of uiomem

uiomem is a Linux device driver for accessing a memory area outside the Linux Kernel management from user space.

uiomem has following features.

  • uiomem can enable CPU cache, so it can access memory at high speed.
  • uiomem can manually invalidiate and flush the CPU cache.
  • uiomem can be freely attached and detached from Linux Kernel.

It is possible to access memory from the user space by opneing the device file(e.g. /dev/uiomem0) and mapping to the user memory space, or using the read()/write() functions.

The start address and size of the allocated memory area can be specified when the device driver is loaded (e.g. when loaded via the insmod command). Some platforms allow to specify them in the device tree.

Supported platforms

  • OS : Linux Kernel Version 4.19, 5.4, 6.1, 6.6, 6.12 (the author tested on 5.4 and 6.1 and 6.6 and 6.12).
  • CPU: ARMv7 Cortex-A9 (Xilinx ZYNQ / Altera CycloneV SoC)
  • CPU: ARM64 Cortex-A53 (Xilinx ZYNQ UltraScale+ MPSoC)
  • CPU: RISC-V (Microchip PolarFire SoC)

Usage

Compile

The following Makefile is included in the repository.

# SPDX-License-Identifier: GPL-2.0 OR MIT
# Copyright (C) 2015-2023 Ichiro Kawazome

#
# For in kernel tree variables
# 
obj-$(CONFIG_UIOMEM) += uiomem.o

#
# For out of kernel tree variables
#
CONFIG_UIOMEM  ?= m

CONFIG_OPTIONS := CONFIG_UIOMEM=$(CONFIG_UIOMEM)

HOST_ARCH ?= $(shell uname -m | sed $(SUBARCH_SCRIPT))
ARCH      ?= $(shell uname -m | sed $(SUBARCH_SCRIPT))

SUBARCH_SCRIPT := -e s/i.86/x86/ -e s/x86_64/x86/ \
		  -e s/sun4u/sparc64/ \
		  -e s/arm.*/arm/ -e s/sa110/arm/ \
		  -e s/s390x/s390/ \
		  -e s/ppc.*/powerpc/ -e s/mips.*/mips/ \
		  -e s/sh[234].*/sh/ -e s/aarch64.*/arm64/ \
		  -e s/riscv.*/riscv/ -e s/loongarch.*/loongarch/

ifeq ($(ARCH), arm)
 ifneq ($(HOST_ARCH), arm)
   CROSS_COMPILE ?= arm-linux-gnueabihf-
 endif
endif
ifeq ($(ARCH), arm64)
 ifneq ($(HOST_ARCH), arm64)
   CROSS_COMPILE ?= aarch64-linux-gnu-
 endif
endif

ifdef KERNEL_SRC
  KERNEL_SRC_DIR := $(KERNEL_SRC)
else
  KERNEL_SRC_DIR ?= /lib/modules/$(shell uname -r)/build
endif
#
# For out of kernel tree rules
#
all:
	$(MAKE) -C $(KERNEL_SRC_DIR) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) M=$(PWD) $(CONFIG_OPTIONS) modules

modules_install:
	$(MAKE) -C $(KERNEL_SRC_DIR) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) M=$(PWD) $(CONFIG_OPTIONS) modules_install

clean:
	$(MAKE) -C $(KERNEL_SRC_DIR) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) M=$(PWD) clean

Install

Load the uiomem kernel driver using insmod. The start address and size of the allocated memory area should be provided as an argument as follows. The device driver is created, and allocates memory area with the specified address and size. The memory area that can be specified must be aligned with the page size. The maximum number of memory area that can be allocated using insmod is 8 (uiomem0/1/2/3/4/5/6/7).

shell$ sudo insmod uiomem.ko uiomem0_addr=0x0400000000 uiomem0_size=0x00040000
[  562.657246] uiomem uiomem0: driver version = 1.1.0-beta.1
[  562.657264] uiomem uiomem0: ioctl version  = 1
[  562.657264] uiomem uiomem0: major number   = 238
[  562.657270] uiomem uiomem0: minor number   = 0
[  562.657275] uiomem uiomem0: range address  = 0x0000000400000000
[  562.657282] uiomem uiomem0: range size     = 262144
[  562.657282] uiomem uiomem0: cached         = 1
[  562.657282] uiomem uiomem0: coherent       = 0
[  562.657282] uiomem uiomem0: sync_operation = ARM64 Native
[  562.657282] uiomem uiomem0: shareable      = 0
[  562.657287] uiomem uiomem.0: driver installed.
shell$ ls -la /dev/uiomem0
crw------- 1 root root 238, 0 Oct 21 17:36 /dev/uiomem0

The module can be uninstalled by the rmmod command.

shell$ sudo rmmod uiomem
[  657.672544] uiomem uiomem.0: driver removed.

Configuration via the device tree file

In addition to the allocation via the insmod command and its arguments, memory area can be allocated by specifying the reg property in the device tree file. When a device tree file contains an entry like the following, uiomem will allocate memory area and create device drivers when loaded by insmod.

		#address-cells = <2>;
		#size-cells    = <2>;
		uiomem_plmem {
			compatible = "ikwzm,uiomem";
			device-name = "uiomem0";
			minor-number = <0>;
			reg = <0x04 0x00000000 0x0 0x00040000>;
		};

shell$ sudo insmod uiomem.ko
[  773.889476] uiomem uiomem0: driver version = 1.1.0-beta.1
[  773.889496] uiomem uiomem0: ioctl version  = 1
[  773.889496] uiomem uiomem0: major number   = 237
[  773.889501] uiomem uiomem0: minor number   = 0
[  773.889506] uiomem uiomem0: range address  = 0x0000000400000000
[  773.889512] uiomem uiomem0: range size     = 262144
[  773.889512] uiomem uiomem0: cached         = 1
[  773.889512] uiomem uiomem0: coherent       = 0
[  773.889518] uiomem uiomem0: sync_operation = ARM64 Native
[  773.889512] uiomem uiomem0: shareable      = 0
[  773.889518] uiomem 400000000.uiomem_plbram: driver installed.
shell$ ls -la /dev/uiomem0
crw------- 1 root root 237, 0 Oct 21 17:40 /dev/uiomem0

The following properties can be set in the device tree.

  • compatible
  • reg
  • memory-region
  • cache-off
  • cache-noncoherent
  • cache-coherent
  • shareable
  • minor-number
  • device-name
  • sync-offset
  • sync-size
  • sync-direction

compatible

The compatible property is used to set the corresponding device driver when loading uiomem. The compatible property is mandatory. Be sure to specify compatible property as "ikwzm,uiomem".

reg

The reg property specifies the physical address and size. The reg property is used when uiomem allocates a buffer outside the management of Linux Kernel. The memory area that can be specified must be aligned with the page size. Either the reg property or the memory-region property is required.

		#address-cells = <2>;
		#size-cells = <2>;
		uiomem@0xFFFC0000 {
			compatible = "ikwzm,uiomem";
			reg = <0x0 0xFFFC0000 0x0 0x00040000>;
		};

memory-region

The memory-region property specifies the memory region allocated for reserved memory. The memory region specified by the memory-region property must always have the no-map property specified. Either the reg property or the memory-region property is required.

		#address-cells = <2>;
		#size-cells = <2>;
		reserved_memory {
			ranges;
			image_buf0: image_buf@0 {
				no-map;
				reg = <0x0 0x70000000 0x0 0x10000000>;
				label = "image_buf0";
			};
		};
		uiomem@image_buf0 {
			compatible = "ikwzm,uiomem";
			memory-region = <&image_buf0>;
		};

cache-off

The cache-off property specifies that uiomem is treated as non-cacheable and coherent.

		uiomem0 {
			compatible = "ikwzm,uiomem";
			reg = <0x0 0xFFFC0000 0x0 0x00040000>;
			cache-off;
		};

cache-noncoherent

The cache-noncoherent property specifies that uiomem is treated as cacheable but non-coherent.

		uiomem0 {
			compatible = "ikwzm,uiomem";
			reg = <0x0 0xFFFC0000 0x0 0x00040000>;
			cache-noncoherent;
		};

cache-coherent

The cache-coherent property specifies that uiomem is treated as cacheable and coherent.

		uiomem0 {
			compatible = "ikwzm,uiomem";
			reg = <0x0 0xFFFC0000 0x0 0x00040000>;
			cache-coherent;
		};

shareable

The shareable property is specified when multiple uiomem shares the memory space specified by reg property.

		#address-cells = <2>;
		#size-cells = <2>;
		uiomem0 {
			compatible = "ikwzm,uiomem";
			reg = <0x0 0xFFFC0000 0x0 0x00040000>;
			shareable;
		};
		uiomem1 {
			compatible = "ikwzm,uiomem";
			reg = <0x0 0xFFFC0000 0x0 0x00040000>;
			shareable;
		};

minor-number

The minor-number property is used to set the minor number. The valid minor number range is 0 to 255. A minor number provided as insmod argument will has higher precedence, and when definition in the device tree has colliding number, creation of the device defined in the device tree will fail.

The minor-number property is optional. When the minor-number property is not specified, uiomem automatically assigns an appropriate one.

		uiomem0 {
			compatible = "ikwzm,uiomem";
			minor-number = <0>;
			reg = <0x0 0xFFFC0000 0x0 0x00040000>;
		};

device-name

The device-name property is used to set the name of device.

The device-name property is optional. The device name is determined as follow:

  1. If device-name property is specified, the value of device-name property is used.
  2. If device-name property is not present, and if minor-number property is specified, sprintf("uiomem%d", minor-number) is used.

sync-offset

The sync-offset property is used to set the start of the buffer range when manually controlling the cache of uiomem.

The sync-offset property is optional. When the sync-offset property is not specified, sync-offset is set to <0>.

sync-size

The sync-size property is used to set the size of the buffer range when manually controlling the cache of uiomem.

The sync-size property is optional. When the sync-size property is not specified, sync-size is set to ths size specified by the reg property.

sync-direction

The sync-direction property is used to set the direction of D

Related Skills

View on GitHub
GitHub Stars14
CategoryDevelopment
Updated11d ago
Forks3

Security Score

95/100

Audited on Mar 30, 2026

No findings