Linux 3/1 split and physical map
I'm trying to understand the Linux 3/1 split (or 2/2, 1/3, any) and how mapping to physical memory work. Let's assume x86.
What I don't understand in particular is why the kernel's 1GiB in va[3GiB, 4GiB) is always mapped to pa[0, 1GiB]. The split is at (virtual) PAGE_OFFSET
.
What if I have more memory? What if I have less? Where does all memory for user-space go?
From TLDP I understand that the bottom physical 1GiB is always for the kernel (why?). High memory is used (by this post) when the virtual address space is smaller than the physical address space, because the memory is a lot and it would be wasted otherwise (right?); in x86-64 it is not being used because the virtual address space is anormous.
One thing to keep always the kernel there might be that on context switches current
remains the same and there's no need to change cr3
.
This answer says:
The High Memory is the segment of memory that user-space programs can address. It cannot touch Low Memory.
Low Memory is the segment of memory that the Linux kernel can address directly. If the kernel must access High Memory, it has to map it into its own address space first.
Are people overloading the terms "low memory" and "high memory"?
Finally, LDD3 says:
The kernel cannot directly manipulate memory that is not mapped into the kernel's address space. The kernel, in other words, needs its own virtual address for any memory it must touch directly. Thus, for many years, the maximum amount of physical memory that could be handled by the kernel was the amount that could be mapped into the kernel's portion of the virtual address space, minus the space needed for the kernel code itself. As a result, x86-based Linux systems could work with a maximum of a little under 1 GB of physical memory.
Does this refer to the fact that a pointer p
in the kernel must be hold a virtual address, not a physical one, as mapping always applies? Why this "1GiB of physical memory" restriction?
linux linux-kernel memory
add a comment |
I'm trying to understand the Linux 3/1 split (or 2/2, 1/3, any) and how mapping to physical memory work. Let's assume x86.
What I don't understand in particular is why the kernel's 1GiB in va[3GiB, 4GiB) is always mapped to pa[0, 1GiB]. The split is at (virtual) PAGE_OFFSET
.
What if I have more memory? What if I have less? Where does all memory for user-space go?
From TLDP I understand that the bottom physical 1GiB is always for the kernel (why?). High memory is used (by this post) when the virtual address space is smaller than the physical address space, because the memory is a lot and it would be wasted otherwise (right?); in x86-64 it is not being used because the virtual address space is anormous.
One thing to keep always the kernel there might be that on context switches current
remains the same and there's no need to change cr3
.
This answer says:
The High Memory is the segment of memory that user-space programs can address. It cannot touch Low Memory.
Low Memory is the segment of memory that the Linux kernel can address directly. If the kernel must access High Memory, it has to map it into its own address space first.
Are people overloading the terms "low memory" and "high memory"?
Finally, LDD3 says:
The kernel cannot directly manipulate memory that is not mapped into the kernel's address space. The kernel, in other words, needs its own virtual address for any memory it must touch directly. Thus, for many years, the maximum amount of physical memory that could be handled by the kernel was the amount that could be mapped into the kernel's portion of the virtual address space, minus the space needed for the kernel code itself. As a result, x86-based Linux systems could work with a maximum of a little under 1 GB of physical memory.
Does this refer to the fact that a pointer p
in the kernel must be hold a virtual address, not a physical one, as mapping always applies? Why this "1GiB of physical memory" restriction?
linux linux-kernel memory
"Let's assume x86." "What if I have more memory?" One answer is you can run x86-64. "Do not worry about the details of x86 CPUs which would only apply when running in the legacy 32-bit modes. Linux for the 32-bit modes is not used as much. It may even be considered "in a state of benign neglect for several years". See 32-Bit x86 support in Fedora [LWN.net, 2017]. The 3/1 split only applies to x86-32.
– sourcejedi
Feb 12 at 20:31
@sourcejedi I'm reading resources and books that deal with them. Regardless, the question remains open for me. "Don't worry about that" is not an answer to my questions
– norake
Feb 12 at 21:52
I was quoting myself carelessly without rephrasing. The question is potentially still relevant e.g. on 32 bit ARM. But it should be edited to qualify that you are genuinely interested in a 32 bit platform, not just "x86", it is too confusing. If someone says they are running on an x86 server, they almost certainly mean x86-64.
– sourcejedi
Feb 13 at 8:27
add a comment |
I'm trying to understand the Linux 3/1 split (or 2/2, 1/3, any) and how mapping to physical memory work. Let's assume x86.
What I don't understand in particular is why the kernel's 1GiB in va[3GiB, 4GiB) is always mapped to pa[0, 1GiB]. The split is at (virtual) PAGE_OFFSET
.
What if I have more memory? What if I have less? Where does all memory for user-space go?
From TLDP I understand that the bottom physical 1GiB is always for the kernel (why?). High memory is used (by this post) when the virtual address space is smaller than the physical address space, because the memory is a lot and it would be wasted otherwise (right?); in x86-64 it is not being used because the virtual address space is anormous.
One thing to keep always the kernel there might be that on context switches current
remains the same and there's no need to change cr3
.
This answer says:
The High Memory is the segment of memory that user-space programs can address. It cannot touch Low Memory.
Low Memory is the segment of memory that the Linux kernel can address directly. If the kernel must access High Memory, it has to map it into its own address space first.
Are people overloading the terms "low memory" and "high memory"?
Finally, LDD3 says:
The kernel cannot directly manipulate memory that is not mapped into the kernel's address space. The kernel, in other words, needs its own virtual address for any memory it must touch directly. Thus, for many years, the maximum amount of physical memory that could be handled by the kernel was the amount that could be mapped into the kernel's portion of the virtual address space, minus the space needed for the kernel code itself. As a result, x86-based Linux systems could work with a maximum of a little under 1 GB of physical memory.
Does this refer to the fact that a pointer p
in the kernel must be hold a virtual address, not a physical one, as mapping always applies? Why this "1GiB of physical memory" restriction?
linux linux-kernel memory
I'm trying to understand the Linux 3/1 split (or 2/2, 1/3, any) and how mapping to physical memory work. Let's assume x86.
What I don't understand in particular is why the kernel's 1GiB in va[3GiB, 4GiB) is always mapped to pa[0, 1GiB]. The split is at (virtual) PAGE_OFFSET
.
What if I have more memory? What if I have less? Where does all memory for user-space go?
From TLDP I understand that the bottom physical 1GiB is always for the kernel (why?). High memory is used (by this post) when the virtual address space is smaller than the physical address space, because the memory is a lot and it would be wasted otherwise (right?); in x86-64 it is not being used because the virtual address space is anormous.
One thing to keep always the kernel there might be that on context switches current
remains the same and there's no need to change cr3
.
This answer says:
The High Memory is the segment of memory that user-space programs can address. It cannot touch Low Memory.
Low Memory is the segment of memory that the Linux kernel can address directly. If the kernel must access High Memory, it has to map it into its own address space first.
Are people overloading the terms "low memory" and "high memory"?
Finally, LDD3 says:
The kernel cannot directly manipulate memory that is not mapped into the kernel's address space. The kernel, in other words, needs its own virtual address for any memory it must touch directly. Thus, for many years, the maximum amount of physical memory that could be handled by the kernel was the amount that could be mapped into the kernel's portion of the virtual address space, minus the space needed for the kernel code itself. As a result, x86-based Linux systems could work with a maximum of a little under 1 GB of physical memory.
Does this refer to the fact that a pointer p
in the kernel must be hold a virtual address, not a physical one, as mapping always applies? Why this "1GiB of physical memory" restriction?
linux linux-kernel memory
linux linux-kernel memory
edited Feb 12 at 20:26
ctrl-alt-delor
11.7k42159
11.7k42159
asked Feb 12 at 19:58
norakenorake
82
82
"Let's assume x86." "What if I have more memory?" One answer is you can run x86-64. "Do not worry about the details of x86 CPUs which would only apply when running in the legacy 32-bit modes. Linux for the 32-bit modes is not used as much. It may even be considered "in a state of benign neglect for several years". See 32-Bit x86 support in Fedora [LWN.net, 2017]. The 3/1 split only applies to x86-32.
– sourcejedi
Feb 12 at 20:31
@sourcejedi I'm reading resources and books that deal with them. Regardless, the question remains open for me. "Don't worry about that" is not an answer to my questions
– norake
Feb 12 at 21:52
I was quoting myself carelessly without rephrasing. The question is potentially still relevant e.g. on 32 bit ARM. But it should be edited to qualify that you are genuinely interested in a 32 bit platform, not just "x86", it is too confusing. If someone says they are running on an x86 server, they almost certainly mean x86-64.
– sourcejedi
Feb 13 at 8:27
add a comment |
"Let's assume x86." "What if I have more memory?" One answer is you can run x86-64. "Do not worry about the details of x86 CPUs which would only apply when running in the legacy 32-bit modes. Linux for the 32-bit modes is not used as much. It may even be considered "in a state of benign neglect for several years". See 32-Bit x86 support in Fedora [LWN.net, 2017]. The 3/1 split only applies to x86-32.
– sourcejedi
Feb 12 at 20:31
@sourcejedi I'm reading resources and books that deal with them. Regardless, the question remains open for me. "Don't worry about that" is not an answer to my questions
– norake
Feb 12 at 21:52
I was quoting myself carelessly without rephrasing. The question is potentially still relevant e.g. on 32 bit ARM. But it should be edited to qualify that you are genuinely interested in a 32 bit platform, not just "x86", it is too confusing. If someone says they are running on an x86 server, they almost certainly mean x86-64.
– sourcejedi
Feb 13 at 8:27
"Let's assume x86." "What if I have more memory?" One answer is you can run x86-64. "Do not worry about the details of x86 CPUs which would only apply when running in the legacy 32-bit modes. Linux for the 32-bit modes is not used as much. It may even be considered "in a state of benign neglect for several years". See 32-Bit x86 support in Fedora [LWN.net, 2017]. The 3/1 split only applies to x86-32.
– sourcejedi
Feb 12 at 20:31
"Let's assume x86." "What if I have more memory?" One answer is you can run x86-64. "Do not worry about the details of x86 CPUs which would only apply when running in the legacy 32-bit modes. Linux for the 32-bit modes is not used as much. It may even be considered "in a state of benign neglect for several years". See 32-Bit x86 support in Fedora [LWN.net, 2017]. The 3/1 split only applies to x86-32.
– sourcejedi
Feb 12 at 20:31
@sourcejedi I'm reading resources and books that deal with them. Regardless, the question remains open for me. "Don't worry about that" is not an answer to my questions
– norake
Feb 12 at 21:52
@sourcejedi I'm reading resources and books that deal with them. Regardless, the question remains open for me. "Don't worry about that" is not an answer to my questions
– norake
Feb 12 at 21:52
I was quoting myself carelessly without rephrasing. The question is potentially still relevant e.g. on 32 bit ARM. But it should be edited to qualify that you are genuinely interested in a 32 bit platform, not just "x86", it is too confusing. If someone says they are running on an x86 server, they almost certainly mean x86-64.
– sourcejedi
Feb 13 at 8:27
I was quoting myself carelessly without rephrasing. The question is potentially still relevant e.g. on 32 bit ARM. But it should be edited to qualify that you are genuinely interested in a 32 bit platform, not just "x86", it is too confusing. If someone says they are running on an x86 server, they almost certainly mean x86-64.
– sourcejedi
Feb 13 at 8:27
add a comment |
1 Answer
1
active
oldest
votes
The 32-bit x86 is almost as obsolete today as the 16-bit 8086 was when Linux was born in the early 1990s. Back then the 4 GB virtual address space made possible by the 386 was plenty, because a typical desktop machine only had a few ten megabytes of RAM.
Linus made the decision to split up the virtual address space so that the upper 1 GB (starting at address 0xc0000000) was reserved for the kernel, and the lower 3 GB (starting at address 0) was available to the user space process. All physical RAM was then mapped starting at PAGE_OFFSET, i.e. the addresses starting at 3 GB. 1 GB was plenty at the time, since (as I mentioned earlier) the typical amount of physical RAM was way smaller than this, and this split left a comfortable 3 GB space for user space.
Before switching on paging (i.e. the virtual to physical address mapping) the kernel image, containing the kernel code and static data, is loaded to the start of physical memory. (Well, not exactly, but typically starting at 2 MB, because of some quirks of the PC platform.) When paging is turned on, the memory at physical address N ends up at virtual address N + PAGE_OFFSET. This means that the kernel image occupies the lower part of the kernel memory area, typically just a few megabytes.
Note that I have talked about virtual address spaces so far, spaces that are reserved for certain things. To actually use the addresses, you will have to map physical RAM page frames to the virtual addresses. In the early days only a tiny bit of the kernel virtual address space was mapped, because there was so little physical RAM to map, but this changed dramatically quite soon when larger RAM sizes became affordable, leading to the 1 GB space not being enough to address all RAM. Thus the "high memory" mechanism was introduced, which provided a window where parts of the extra RAM was mapped as needed.
So why does the kernel need to have the RAM in its virtual address space. The thing is that the CPU can only (programmatically) access memory through virtual (mapped) addresses. Pointers in registers are pointers to the virtual address space, and so is the instruction pointer that directs program flow. The kernel needs to be able to freely access RAM, for example to zero a buffer that it will later provide to a user space process.
That the kernel has hoarded the whole of RAM into its address space does not mean the user space can't access it. More than one mapping to a RAM page frame can exist; it can be both permanently mapped to the kernel memory space and mapped to some address to a user space when the process is chosen for execution.
I'd like to follow up more, but given this is a comment... by your #3 paragraph, see if I understand: the part of the kernel that's always mapped is 1GiB; in it all the possible mappings for the processes currently running, so when a task accesses *p the mapping/table is already in memory. So every task can run as there exists a table with va->pa (if not, swap/create). If PAS>1GiB, the rest is for additional stuff (pages, structs, whatever user stuff, eg the page for *p above). (If PAS<1GiB, I don't know. I read the kernel can work with just a few MiBs...). Did I understand?
– norake
Feb 14 at 0:33
See my edits to the answer.
– Johan Myréen
Feb 14 at 13:01
Ok, this is a great explanation, I get it now! Thanks so much! I just have to figure out now what happens when the memory is so little (such as in low end devices) or when the memory is so small that barely (or not at all) the kernel image fits in. Thanks again!!
– norake
Feb 14 at 22:36
add a comment |
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "106"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f500256%2flinux-3-1-split-and-physical-map%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
The 32-bit x86 is almost as obsolete today as the 16-bit 8086 was when Linux was born in the early 1990s. Back then the 4 GB virtual address space made possible by the 386 was plenty, because a typical desktop machine only had a few ten megabytes of RAM.
Linus made the decision to split up the virtual address space so that the upper 1 GB (starting at address 0xc0000000) was reserved for the kernel, and the lower 3 GB (starting at address 0) was available to the user space process. All physical RAM was then mapped starting at PAGE_OFFSET, i.e. the addresses starting at 3 GB. 1 GB was plenty at the time, since (as I mentioned earlier) the typical amount of physical RAM was way smaller than this, and this split left a comfortable 3 GB space for user space.
Before switching on paging (i.e. the virtual to physical address mapping) the kernel image, containing the kernel code and static data, is loaded to the start of physical memory. (Well, not exactly, but typically starting at 2 MB, because of some quirks of the PC platform.) When paging is turned on, the memory at physical address N ends up at virtual address N + PAGE_OFFSET. This means that the kernel image occupies the lower part of the kernel memory area, typically just a few megabytes.
Note that I have talked about virtual address spaces so far, spaces that are reserved for certain things. To actually use the addresses, you will have to map physical RAM page frames to the virtual addresses. In the early days only a tiny bit of the kernel virtual address space was mapped, because there was so little physical RAM to map, but this changed dramatically quite soon when larger RAM sizes became affordable, leading to the 1 GB space not being enough to address all RAM. Thus the "high memory" mechanism was introduced, which provided a window where parts of the extra RAM was mapped as needed.
So why does the kernel need to have the RAM in its virtual address space. The thing is that the CPU can only (programmatically) access memory through virtual (mapped) addresses. Pointers in registers are pointers to the virtual address space, and so is the instruction pointer that directs program flow. The kernel needs to be able to freely access RAM, for example to zero a buffer that it will later provide to a user space process.
That the kernel has hoarded the whole of RAM into its address space does not mean the user space can't access it. More than one mapping to a RAM page frame can exist; it can be both permanently mapped to the kernel memory space and mapped to some address to a user space when the process is chosen for execution.
I'd like to follow up more, but given this is a comment... by your #3 paragraph, see if I understand: the part of the kernel that's always mapped is 1GiB; in it all the possible mappings for the processes currently running, so when a task accesses *p the mapping/table is already in memory. So every task can run as there exists a table with va->pa (if not, swap/create). If PAS>1GiB, the rest is for additional stuff (pages, structs, whatever user stuff, eg the page for *p above). (If PAS<1GiB, I don't know. I read the kernel can work with just a few MiBs...). Did I understand?
– norake
Feb 14 at 0:33
See my edits to the answer.
– Johan Myréen
Feb 14 at 13:01
Ok, this is a great explanation, I get it now! Thanks so much! I just have to figure out now what happens when the memory is so little (such as in low end devices) or when the memory is so small that barely (or not at all) the kernel image fits in. Thanks again!!
– norake
Feb 14 at 22:36
add a comment |
The 32-bit x86 is almost as obsolete today as the 16-bit 8086 was when Linux was born in the early 1990s. Back then the 4 GB virtual address space made possible by the 386 was plenty, because a typical desktop machine only had a few ten megabytes of RAM.
Linus made the decision to split up the virtual address space so that the upper 1 GB (starting at address 0xc0000000) was reserved for the kernel, and the lower 3 GB (starting at address 0) was available to the user space process. All physical RAM was then mapped starting at PAGE_OFFSET, i.e. the addresses starting at 3 GB. 1 GB was plenty at the time, since (as I mentioned earlier) the typical amount of physical RAM was way smaller than this, and this split left a comfortable 3 GB space for user space.
Before switching on paging (i.e. the virtual to physical address mapping) the kernel image, containing the kernel code and static data, is loaded to the start of physical memory. (Well, not exactly, but typically starting at 2 MB, because of some quirks of the PC platform.) When paging is turned on, the memory at physical address N ends up at virtual address N + PAGE_OFFSET. This means that the kernel image occupies the lower part of the kernel memory area, typically just a few megabytes.
Note that I have talked about virtual address spaces so far, spaces that are reserved for certain things. To actually use the addresses, you will have to map physical RAM page frames to the virtual addresses. In the early days only a tiny bit of the kernel virtual address space was mapped, because there was so little physical RAM to map, but this changed dramatically quite soon when larger RAM sizes became affordable, leading to the 1 GB space not being enough to address all RAM. Thus the "high memory" mechanism was introduced, which provided a window where parts of the extra RAM was mapped as needed.
So why does the kernel need to have the RAM in its virtual address space. The thing is that the CPU can only (programmatically) access memory through virtual (mapped) addresses. Pointers in registers are pointers to the virtual address space, and so is the instruction pointer that directs program flow. The kernel needs to be able to freely access RAM, for example to zero a buffer that it will later provide to a user space process.
That the kernel has hoarded the whole of RAM into its address space does not mean the user space can't access it. More than one mapping to a RAM page frame can exist; it can be both permanently mapped to the kernel memory space and mapped to some address to a user space when the process is chosen for execution.
I'd like to follow up more, but given this is a comment... by your #3 paragraph, see if I understand: the part of the kernel that's always mapped is 1GiB; in it all the possible mappings for the processes currently running, so when a task accesses *p the mapping/table is already in memory. So every task can run as there exists a table with va->pa (if not, swap/create). If PAS>1GiB, the rest is for additional stuff (pages, structs, whatever user stuff, eg the page for *p above). (If PAS<1GiB, I don't know. I read the kernel can work with just a few MiBs...). Did I understand?
– norake
Feb 14 at 0:33
See my edits to the answer.
– Johan Myréen
Feb 14 at 13:01
Ok, this is a great explanation, I get it now! Thanks so much! I just have to figure out now what happens when the memory is so little (such as in low end devices) or when the memory is so small that barely (or not at all) the kernel image fits in. Thanks again!!
– norake
Feb 14 at 22:36
add a comment |
The 32-bit x86 is almost as obsolete today as the 16-bit 8086 was when Linux was born in the early 1990s. Back then the 4 GB virtual address space made possible by the 386 was plenty, because a typical desktop machine only had a few ten megabytes of RAM.
Linus made the decision to split up the virtual address space so that the upper 1 GB (starting at address 0xc0000000) was reserved for the kernel, and the lower 3 GB (starting at address 0) was available to the user space process. All physical RAM was then mapped starting at PAGE_OFFSET, i.e. the addresses starting at 3 GB. 1 GB was plenty at the time, since (as I mentioned earlier) the typical amount of physical RAM was way smaller than this, and this split left a comfortable 3 GB space for user space.
Before switching on paging (i.e. the virtual to physical address mapping) the kernel image, containing the kernel code and static data, is loaded to the start of physical memory. (Well, not exactly, but typically starting at 2 MB, because of some quirks of the PC platform.) When paging is turned on, the memory at physical address N ends up at virtual address N + PAGE_OFFSET. This means that the kernel image occupies the lower part of the kernel memory area, typically just a few megabytes.
Note that I have talked about virtual address spaces so far, spaces that are reserved for certain things. To actually use the addresses, you will have to map physical RAM page frames to the virtual addresses. In the early days only a tiny bit of the kernel virtual address space was mapped, because there was so little physical RAM to map, but this changed dramatically quite soon when larger RAM sizes became affordable, leading to the 1 GB space not being enough to address all RAM. Thus the "high memory" mechanism was introduced, which provided a window where parts of the extra RAM was mapped as needed.
So why does the kernel need to have the RAM in its virtual address space. The thing is that the CPU can only (programmatically) access memory through virtual (mapped) addresses. Pointers in registers are pointers to the virtual address space, and so is the instruction pointer that directs program flow. The kernel needs to be able to freely access RAM, for example to zero a buffer that it will later provide to a user space process.
That the kernel has hoarded the whole of RAM into its address space does not mean the user space can't access it. More than one mapping to a RAM page frame can exist; it can be both permanently mapped to the kernel memory space and mapped to some address to a user space when the process is chosen for execution.
The 32-bit x86 is almost as obsolete today as the 16-bit 8086 was when Linux was born in the early 1990s. Back then the 4 GB virtual address space made possible by the 386 was plenty, because a typical desktop machine only had a few ten megabytes of RAM.
Linus made the decision to split up the virtual address space so that the upper 1 GB (starting at address 0xc0000000) was reserved for the kernel, and the lower 3 GB (starting at address 0) was available to the user space process. All physical RAM was then mapped starting at PAGE_OFFSET, i.e. the addresses starting at 3 GB. 1 GB was plenty at the time, since (as I mentioned earlier) the typical amount of physical RAM was way smaller than this, and this split left a comfortable 3 GB space for user space.
Before switching on paging (i.e. the virtual to physical address mapping) the kernel image, containing the kernel code and static data, is loaded to the start of physical memory. (Well, not exactly, but typically starting at 2 MB, because of some quirks of the PC platform.) When paging is turned on, the memory at physical address N ends up at virtual address N + PAGE_OFFSET. This means that the kernel image occupies the lower part of the kernel memory area, typically just a few megabytes.
Note that I have talked about virtual address spaces so far, spaces that are reserved for certain things. To actually use the addresses, you will have to map physical RAM page frames to the virtual addresses. In the early days only a tiny bit of the kernel virtual address space was mapped, because there was so little physical RAM to map, but this changed dramatically quite soon when larger RAM sizes became affordable, leading to the 1 GB space not being enough to address all RAM. Thus the "high memory" mechanism was introduced, which provided a window where parts of the extra RAM was mapped as needed.
So why does the kernel need to have the RAM in its virtual address space. The thing is that the CPU can only (programmatically) access memory through virtual (mapped) addresses. Pointers in registers are pointers to the virtual address space, and so is the instruction pointer that directs program flow. The kernel needs to be able to freely access RAM, for example to zero a buffer that it will later provide to a user space process.
That the kernel has hoarded the whole of RAM into its address space does not mean the user space can't access it. More than one mapping to a RAM page frame can exist; it can be both permanently mapped to the kernel memory space and mapped to some address to a user space when the process is chosen for execution.
edited Feb 14 at 13:01
answered Feb 13 at 6:45
Johan MyréenJohan Myréen
7,74711524
7,74711524
I'd like to follow up more, but given this is a comment... by your #3 paragraph, see if I understand: the part of the kernel that's always mapped is 1GiB; in it all the possible mappings for the processes currently running, so when a task accesses *p the mapping/table is already in memory. So every task can run as there exists a table with va->pa (if not, swap/create). If PAS>1GiB, the rest is for additional stuff (pages, structs, whatever user stuff, eg the page for *p above). (If PAS<1GiB, I don't know. I read the kernel can work with just a few MiBs...). Did I understand?
– norake
Feb 14 at 0:33
See my edits to the answer.
– Johan Myréen
Feb 14 at 13:01
Ok, this is a great explanation, I get it now! Thanks so much! I just have to figure out now what happens when the memory is so little (such as in low end devices) or when the memory is so small that barely (or not at all) the kernel image fits in. Thanks again!!
– norake
Feb 14 at 22:36
add a comment |
I'd like to follow up more, but given this is a comment... by your #3 paragraph, see if I understand: the part of the kernel that's always mapped is 1GiB; in it all the possible mappings for the processes currently running, so when a task accesses *p the mapping/table is already in memory. So every task can run as there exists a table with va->pa (if not, swap/create). If PAS>1GiB, the rest is for additional stuff (pages, structs, whatever user stuff, eg the page for *p above). (If PAS<1GiB, I don't know. I read the kernel can work with just a few MiBs...). Did I understand?
– norake
Feb 14 at 0:33
See my edits to the answer.
– Johan Myréen
Feb 14 at 13:01
Ok, this is a great explanation, I get it now! Thanks so much! I just have to figure out now what happens when the memory is so little (such as in low end devices) or when the memory is so small that barely (or not at all) the kernel image fits in. Thanks again!!
– norake
Feb 14 at 22:36
I'd like to follow up more, but given this is a comment... by your #3 paragraph, see if I understand: the part of the kernel that's always mapped is 1GiB; in it all the possible mappings for the processes currently running, so when a task accesses *p the mapping/table is already in memory. So every task can run as there exists a table with va->pa (if not, swap/create). If PAS>1GiB, the rest is for additional stuff (pages, structs, whatever user stuff, eg the page for *p above). (If PAS<1GiB, I don't know. I read the kernel can work with just a few MiBs...). Did I understand?
– norake
Feb 14 at 0:33
I'd like to follow up more, but given this is a comment... by your #3 paragraph, see if I understand: the part of the kernel that's always mapped is 1GiB; in it all the possible mappings for the processes currently running, so when a task accesses *p the mapping/table is already in memory. So every task can run as there exists a table with va->pa (if not, swap/create). If PAS>1GiB, the rest is for additional stuff (pages, structs, whatever user stuff, eg the page for *p above). (If PAS<1GiB, I don't know. I read the kernel can work with just a few MiBs...). Did I understand?
– norake
Feb 14 at 0:33
See my edits to the answer.
– Johan Myréen
Feb 14 at 13:01
See my edits to the answer.
– Johan Myréen
Feb 14 at 13:01
Ok, this is a great explanation, I get it now! Thanks so much! I just have to figure out now what happens when the memory is so little (such as in low end devices) or when the memory is so small that barely (or not at all) the kernel image fits in. Thanks again!!
– norake
Feb 14 at 22:36
Ok, this is a great explanation, I get it now! Thanks so much! I just have to figure out now what happens when the memory is so little (such as in low end devices) or when the memory is so small that barely (or not at all) the kernel image fits in. Thanks again!!
– norake
Feb 14 at 22:36
add a comment |
Thanks for contributing an answer to Unix & Linux Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f500256%2flinux-3-1-split-and-physical-map%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
"Let's assume x86." "What if I have more memory?" One answer is you can run x86-64. "Do not worry about the details of x86 CPUs which would only apply when running in the legacy 32-bit modes. Linux for the 32-bit modes is not used as much. It may even be considered "in a state of benign neglect for several years". See 32-Bit x86 support in Fedora [LWN.net, 2017]. The 3/1 split only applies to x86-32.
– sourcejedi
Feb 12 at 20:31
@sourcejedi I'm reading resources and books that deal with them. Regardless, the question remains open for me. "Don't worry about that" is not an answer to my questions
– norake
Feb 12 at 21:52
I was quoting myself carelessly without rephrasing. The question is potentially still relevant e.g. on 32 bit ARM. But it should be edited to qualify that you are genuinely interested in a 32 bit platform, not just "x86", it is too confusing. If someone says they are running on an x86 server, they almost certainly mean x86-64.
– sourcejedi
Feb 13 at 8:27