I dont think kernel memory can ever be swapped out, but definitely
user process memory is swappable. If I am wrong correct me.
Check out this thread
http://www.ussg.iu.edu/hypermail/linux/kernel/9706.2/0388.html
What bothered be was the macro __pa() that translates virtual to physical
addresses by simple substruction. This would imply that virtual
addresses are contiguous in RAM, external fragmentation, and other ouchies.
kernel virtual address space is is not fragmented in physical memory,
its contigous. This does not mean that kernel do not need the page
Consider this case:
you have 4M RAM. all is used except two pages: the one starting with
address 0x400 and the one starting with address 0x600.
now suppose you need a 8K buffer (not for DMA, but for your own usage),
you don't have any such buffer, although you do have 8K of free RAM.
This, AFAIK, is called external fragmentation.
Paging helps you solve this problem by mapping higher addresses to those
pages, so although not contiguous in RAM they are contiguous in VM.
It a little suprised me to learn that the Linux kernel maps its memory
contiguously into RAM, and still avoid such external fragmentation.
Indeed "Understanding the linux virtual memory manager" page 113, states
that large blocks are allocated with vmalloc to avoid external
fragmentation.
(available here: http://www.skynet.ie/~mel/projects/vm/)
table for it self. Kernel do have the page table for its virtual to
physical memory mapping as that is needed by CPU while addresing in
Of course. The CPU does not treat kernel addresses different than user
addresses. The page table built for the CPU is not the issue. They tell
it what ever mapping the OS decides to have.
It's the mapping that we discuss.
this is not at all true for user space virtual address. mapping of
user space virtual address is always done through traversal of page
table for that process, as the virtual address of user space process
can be fragmented in terms of physical pages.
User space, is much simpler.
Hope all this does not confuse you further ;-) ..... well its bit
confusing at initial stage. I am also not much confident in all this,
so experts on list, please correct me if I am wrong anywhere :-)
you are not wrong: it _is_ confusing :)
I read some and eventually saw that:
The kernel has 1G of virtual addresses (usually). The lower part of this
1G is used to map the physical memory. The upper part of it is used for
virtual addresses.
So we have this mem-map:
[ map of ram | 8MB | more kernel memory ]
^ ^ ^ ^
PAGE_OFFSET high_memory VMALLOC_START 4G
Where PAGE_OFFSET is 0xC0000000.
high_memory is a variable that tells where the mapping of physical RAM
ends.
VMALLOC_START points to where starts the area that is allocated virtually.
So, addresses between PAGE_OFFSET and high_memory can be translated with
__pa(), others cannot.
Not sure of this ......
I copied the diagram given in "Understanding the Linux Kernel".
There's another drawing at "understanding the linux virtual memory
manager" page 54, that shows more or less the same thing: you have your
mapping of the RAM and you have the VMALLOC area.
For example, suppose you have a machine with 64M.
Then:
PAGE_OFFSET = 0xC0000000
high_memory = PAGE_OFFSET + 64M = 0xC4000000
VMALLOC_START = 0xC4800000
kernel virtual addresses 0xC0000000 - 0xC4000000 correspond to RAM
physical addresses 0x000000 - 0x04000000 (let's ignore the few pages left
unused in the begning of RAM).
If you do vmalloc you'll get an address above 0xC4800000. This address
will be mapped to some physical page. Note that that page is mapped twice
by the kernel.
But I know that in physical memory first 8K of memory is left blank as
a hole, this means the first virtual address of kernel will be mapped
to 8K and not 0 physical address. The reason for this is given in
source code itself:
http://lxr.linux.no/source/include/asm-i386/pgtable.h#L72
As mentioned in source code also, this is done to catch any mistakes
of null pointer de-reffrening in kernel code.
I think the BIOS also uses these addresses on some architecturs, and
that's another reason.
I am not sure how Talib allocated his structures. If it's with kmalloc the
__pa() and virt_to_page() can work for him. And I guess these addresses
are always valid as they map the RAM (which is always there hopefully).
If these are modified by user space application and the passed to
kernel, they might not be mappable to some physical page frame, so
need to cross check.
I am not sure I understand what you wrote here.
Continuing my previous example. Suppose Talib kmalloc-ed and got the
virtual pointer: 0xC2000000. This is mapped to the physical address
0x02000000 in RAM.
Now suppose the user is playing tricks on Talib and gives him back the
pointer: 0xC2100000. Is it possible for this pointer not to be mapped?
Isn't this virtual pointer mapped to the physical address 0x02100000.
Regardless to whether it is a kernel page, user page or free page, reading
the RAM at that address will give you something.
Or are you suggesting that the kernel unmaps this page (invalidate the
corresponding entry in the CPU page table) so accessing this address will
cause a CPU exception?
What I still don't understand is how is this mapping happens on machines
where the kernel space is of size 1G and they have more than 1G of RAM.
Probably only a small portion of the RAM is mapped.
Please elaborate more on this, I could not get that want to say by this.
I think I found the answer in page 54 "understanding the linux virtual
memory management".
Consider a 32-bit machine with 12G RAM. You can't map the whole RAM into
your 1G. What would you map? If you mapped 1G you won't leave room for the
VMALLOC area.
From what I understand from "UtLVMM" in such high-memory system a third
area is introduced: kmap-addr-space. which is used to map higher memory.
(and obviously you don't map the whole RAM)
Hayim.
--
Kernelnewbies: Help each other learn about the Linux kernel.
Archive: http://mail.nl.linux.org/kernelnewbies/
FAQ: http://kernelnewbies.org/faq/