"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:
- sudo vi /etc/default/grub
- Update with mem=, e.g. GRUB_CMDLINE_LINUX_DEFAULT="quiet splash mem=4G"
- sudo update-grub
- sudo reboot
Once the system is booted up, we can observe that Kernel
can only see ~4GB though the memory configured is 8GB.
ioremap is the key API to claim this memory back.
Here is the sample kernel module.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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"); |
And Makefile.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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 |
Once we deploy the module, we can see prints in dmesg confirming the memory claim.
Comments
Post a Comment