Allocating memory in OS - linux-kernel

To allocate memory dynamically we use some system calls . so the operating system allocates memory on the heap of corresponding process. but how is memory allocated in operating system itself?
how allocates operating system memory when some data structure (e.g process tabel) must be created? dose OS kernel has its own stack and heap?

The Linux operating system does use have its own fixed size stack for each thread. you can see the stack in the source code defining thread_union.
When a syscall is preformed in x86/x64 the kernel swaps out the GS segment and CR3 registers to refer to its own memory and then uses the GS segment register to locate cpu_current_top_of_stack which points to the corresponding kernel stack pointer for the calling thread. You can see this in entry_SYSCALL_64.
When the kernel needs to allocate dynamic memory it uses kamlloc which uses the slob allocator.

Related

How does macOS allocate stack and heap for a process?

I want to know how macOS allocate stack and heap memory for a process, i.e. the memory layout of a process in macOS. I only know that the segments of a mach-o executable are loaded into pages, but I can't find a segment that correspond to stack or heap area of a process. Is there any document about that?
Stacks and heaps are just memory. The only think that makes a stack a stack or a heap or a heap is the way it is accessed. Stacks and heaps are allocated the same way all memory is: by mapping pages into the logical address space.
Let's take a step back - the Mach-o format describes mapping the binary segments into virtual memory. Importantly the memory pages you mentioned have read write and execute permissions. If it's an executable(i.e. not a dylib) it must contain the __PAGEZERO segment with no permissions at all. This is the safe guard area to prevent accessing low addresses of virtual memory by accident (here falls the infamous Null pointer exception and such if attempting to access zero memory address).
__TEXT read executable (typically without write) segment follows which in virtual memory will contain the file representation itself. This implies all the executable code lives here. Also immmutable data like string constants.
The order may vary, but usually next you will encounter __LINKEDIT read only segment. This is the segment dyld uses to setup externally loaded functions, this is too broad to cover here, but there are numerous answers on the topic.
Finally we have the readable writable __DATA segment the first place a process can actually write to. This is used for global/static variables, external addresses to calls populated by dyld.
We have roughly covered the process initial setup when it will launch through either LC_UNIXTHREAD or in modern MacOS (10.7+) LC_MAIN. This starts the process main thread. Each thread must contain it's own stack. The creation of it is handled by operating system (including allocating it). Notice so far the process has no awareness of the heap at all (it's the operating system that's doing the heavy lifting to prepare the stack).
So to sum up so far we have 2 independent sources of memory - the process memory representing the Mach-o structure (size is fixed and determined by the executable structure) and the main thread stack (also with predefined size). The process is about to run a C-like main function , any local variables declared would move the thread stack pointer, likewise any calls to functions (local and external) to at least setup the stack frame for return address. Accessing a global/static variable would reference the __DATA segment virtual memory directly.
Reserving stack space in x86-64 assembly would look like this:
sub rsp,16
There are some great SO anwers on System V / AMD64 ABI (which includes MacOS) requirements for stack alignment like this one
Any new thread created will have its own stack to allow setting up stack frames for local variables and calling functions.
Now we can cover heap allocation - which is mitigated by the libSystem (aka MacOS C standard library) delivering the malloc/free. Internally this is handled by mmap & munmap system calls - the kernel API for managing memory pages.
Using those system calls directly is possible, but might turned out inefficient, thus an internal memory pool is utilised by malloc/free to limit the number of system calls (which are costly to make).
The changing addresses you mentioned in the comment are caused by:
ASLR aka PIE (position independent code) for process memory , which is a security measure randomizing the start of virtual memory
Thread local stacks being prepared by the operating system

Does Linux immediately allocate memory for process after mmap()?

I am reading the source code of mmap(), and I found the Linux kernel will make the files map into the vma struct. vma only represents memory areas. So, will the OS immediately allocate physical memory for the process after mmap()?
No, Linux may defer allocation of the physical memory, requested by mmap, until that memory will be accessed.
When application accesses an unmapped memory, page fault exception is triggered; when handle this exception, Linux may map that accessed memory, allowing the application to continue.

Allocating a physical memory buffer in linux

I have an SoC which has both DSP and ARM cores on it and I would like to create a section of shared memory that both my userspace software, and DSP software are able to access. What would be the best way to allocate a buffer like this in Linux? Here is a little background, right now what I have is a kernel module in which I use kmalloc() to get a kernel buffer, I then use the __pa() macro from asm/page.h to get the physical address of my kernel buffer. I save this address as a sysfs entry so that my userspace code can get the physical address of this buffer. I can then write this address to the DSP so it knows where the shared memory location is, and I can also mmap /dev/mem or my own kernel module so that I can access this buffer from userspace (I could also use the read/write fileops).
For some reason I feel like this is overboard but I cannot find the best way to do what I am trying to do.
Would it be possible to just mmap \dev\mem a section of memory and just read and write to this section? My feeling is that this would not 'lock' this section of memory from the kernel, thus the kernel could still read/write to this memory without me knowing. Is this the case. After reading the memory management chapter of LDD3 I see that mmap creates a new VMA of the mapping. Would this lock this area of memory so that other processes would not get allocated this section of memory?
Any and all help is appreciated
Depending on the kind of DMA you're using, you need to allocate the buffer with dma_alloc_coherent(), or use standard allocations and the dma_map_* functions.
(You must not use __pa(); physical addresses are not necessarily the same as DMA bus addresses.)
To map the buffers to user space, use dma_mmap_coherent() for coherent buffers, or map the memory pages manually for streaming buffers.
For a similar requirement of mine, I had reserved about 16 MB of memory towards the end of ram and used it in both kernel and user space. Suppose you have 128 MB ram, you can set BOOTMEM argument as 112 MB in your boot loader. I am assuming you are using uboot. This will reserve 16 MB towards the end of the ram. Now in kernel and user space you can map this area and use it as shared memory.

how do we use kmalloc in linux driver code

How will I come to know that where exactly or at what point I should use the kmalloc() to allocate a memory to the device in the device driver?
Is it during initialization or during open? As in malloc,wil kmalloc allocates memory dynamically?
In general, you can use kmalloc() when you need physically contigous memory in kernel space.
You can use this during init/open depending on your use case.
If you kmalloc in init() but never use the device, then memory allocated is waste.
If kmalloc is used in open(), memory allocated is actually used because memory is allocated only if device is used.
Also, note that you can use vmalloc() in kernel in case you are not in need of physically contigous memory allocation.
It depends on when you need it. There is no hard and fast rule.
For eg, in the i2c driver in linux kernel, there are two kmalloc calls and none in initialization or any specific function.
And yes, it acts similar to user space malloc call and allocates memory dynamically.

Clarification on stack memory - where is it?

As far as I know, stack isn't a PE section mapped memory (i.e. it's not mapped into a PE win32 section).
My question is: where does the stack memory reside? Where does the operating system put it?
Does the operating system allocate a page of memory for the stack when a process is started and change the ESP register value to that page before jumping to the process' code? I'm kind of confused..
The operating system puts it wherever it can find some free space in the virtual address space. It is not part of the PE file.
There is a single virtual address space for each process. The modules are loaded into that address space. The heap is created in that address space. And so is the stack.
For an unmanaged process, the OS reserves the entire stack allocation for a new thread, and then commits the memory on demand. Managed .net processes have a different policy. They commit and reserve the entire stack allocation when each thread is created.

Resources