"MEM=" Kernel paramater (limiting the total amount of memory available to the kernel)

In this post, I would like to demonstrate experiment on how to restrict memory to be considered by kernel and use/claim that memory later.

The mem= limits the total amount of memory available to the kernel, rather than reserving a specific region of memory for special purposes.

What it does: Limits the total memory the kernel sees and uses.

Effect: The kernel will ignore any memory beyond the specified amount. For example, if you pass mem=512M, the kernel will only use the first 512 MB of RAM and ignore the rest of the memory.

Use case: Testing scenarios with reduced memory or debugging purposes, but not suitable for reserving specific memory regions for custom uses.

Here is my Ubuntu System setting where 8GB memory is configured.

Now I would pass MEM=4G as kernel command line parameter through bootloader which happens to be GRUB in this case. here are the typical steps:
  1. sudo vi /etc/default/grub
  2. Update with mem=, e.g. GRUB_CMDLINE_LINUX_DEFAULT="quiet splash mem=4G"
  3. sudo update-grub
  4. sudo reboot
Once the system is booted up, we can observe that Kernel can only see ~4GB though the memory configured is 8GB.

Now, interesting part is we can claim boot time reserved memory(4G in this case) by writing simple kernel module. 

ioremap is the key API to claim this memory back.

Here is the sample kernel module.
#include <linux/io.h> // For ioremap()
#include <linux/kernel.h> // For printk()
#include <linux/module.h> // For kernel module macros
#define RESERVED_START 0x100000000 // Start physical address
#define RESERVED_SIZE 0x100000000 // Size of memory (4 GB)
static void __iomem *mapped_memory;
static int __init my_module_init(void)
{
// Map the reserved memory region
mapped_memory = ioremap(RESERVED_START, RESERVED_SIZE);
if (!mapped_memory) {
pr_err("Failed to map reserved memory\n");
return -ENOMEM;
}
pr_info("Reserved memory mapped at virtual address %p\n", mapped_memory);
strcpy((char *)mapped_memory, "Hello Raxesh");
pr_info("%s\n", (char *)mapped_memory);
return 0;
}
static void __exit my_module_exit(void)
{
if (mapped_memory) {
iounmap(mapped_memory);
pr_info("Reserved memory unmapped\n");
}
}
module_init(my_module_init);
module_exit(my_module_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Raxesh Oriya");
MODULE_DESCRIPTION("Map reserved memory with ioremap");
view raw ioremap.c hosted with ❤ by GitHub

And Makefile.
# Kbuild part of Makefile
ifneq ($(KERNELRELEASE),)
obj-m := ioremap.o
# command line part of Makefile
else
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
build:
$(MAKE) -C $(KDIR) M=$(PWD) modules
clean:
$(MAKE) -C $(KDIR) M=$(PWD) clean
endif
view raw Makefile hosted with ❤ by GitHub

Once we deploy the module, we can see prints in dmesg confirming the memory claim.



Comments

Popular posts from this blog

MBR partitioning with 'parted' utility

Disk Partitioning: MBR vs GPT

Replace default splash screen in Yocto