我正在执行页表遍历。当我准备更新内核时出现错误:
\n\nkernel/sys.c: In function \xe2\x80\x98__do_sys_get_page_info\xe2\x80\x99:\nkernel/sys.c:2745:23: error: passing argument 1 of \xe2\x80\x98pud_offset\xe2\x80\x99 from incompatible pointer type [-Werror=incompatible-pointer-types]\n pud = pud_offset(pgd, vmpage);\n ^\nIn file included from ./include/linux/mm.h:99:0,\n from kernel/sys.c:19:\n./arch/x86/include/asm/pgtable.h:905:22: note: expected \xe2\x80\x98p4d_t * {aka struct <anonymous> *}\xe2\x80\x99 but argument is of type \xe2\x80\x98pgd_t * {aka struct <anonymous> *}\xe2\x80\x99\n static inline pud_t *pud_offset(p4d_t *p4d, unsigned long address)\n ^\nRun Code Online (Sandbox Code Playgroud)\n\n这是使用代码的地方:
\n\n....\nint loc, ref, dirty;\nstruct vm_area_struct *vma;\nunsigned long vmpage;\nstruct mm_struct *task_mm = task->mm;\nif ((task_mm && task_mm->mmap))\n{\n int i;\n pgd_t *pgd;\n pud_t *pud;\n …Run Code Online (Sandbox Code Playgroud) 假设两个地址空间共享一块较大的非连续内存。系统可能希望在它们之间共享物理页表。这些表不会使用全局位(即使支持),并且如果支持的话会将它们绑定到asid。
这样做有直接的好处,因为数据缓存的污染比副本、更少的固定内存等污染要少。
页面遍历是否在任何已知架构中明确利用了这一点?如果是这样,这是否意味着mmu正在根据物理标签显式缓存和共享内部页面树节点?
很抱歉提出了多个问题;这确实是一件坏事。我正在尝试确定是否值得为此设计一个测量测试。
根据手册页:
* VmLck: Locked memory size (see mlock(3)).
* VmPin: Pinned memory size (since Linux 3.2).
These are pages that can't be moved because something needs
to directly access physical memory.
Run Code Online (Sandbox Code Playgroud)
我知道什么是锁定内存(mlock、mlockall),但老实说我不明白固定内存的概念以及它与锁定内存有何不同。
有人可以举例说明吗?
我不确定这个问题是否有意义,但假设我有一个指向某些内存的指针:
char *mem;
size_t len;
Run Code Online (Sandbox Code Playgroud)
是否可以以某种方式将 的内容mem作为只读映射映射到另一个地址?即我想获得一个指针mem2,以便mem2 != mem进行mem2[i]实际读取mem[i](而不进行复制)。
我的最终目标是获取不连续的内存块,并通过将它们彼此相邻映射来使它们看起来是连续的。
我考虑的一种方法是使用fmemopenand then mmap,但是没有与 的结果关联的文件描述符fmemopen。
我正在构建一个 RISC-V 模拟器,它基本上将整个 ELF 文件加载到内存中。
到目前为止,我使用了 risc-v 基金会提供的预编译测试二进制文件,该二进制文件在本节的开头处方便地有一个入口点.text。
例如:
> riscv32-unknown-elf-objdump ../riscv32i-emulator/tests/simple -d
../riscv32i-emulator/tests/simple: file format elf32-littleriscv
Disassembly of section .text.init:
80000000 <_start>:
80000000: 0480006f j 80000048 <reset_vector>
...
Run Code Online (Sandbox Code Playgroud)
进入这个项目时,我对 ELF 文件了解不多,所以我只是假设每个 ELF 的入口点与该部分的开头完全相同.text。
当我编译自己的二进制文件时出现了问题,我发现实际的入口点并不总是与该部分的开头相同.text,但它可能位于其中的任何位置,如下所示:
> riscv32-unknown-elf-objdump a.out -d
a.out: file format elf32-littleriscv
Disassembly of section .text:
00010074 <register_fini>:
10074: 00000793 li a5,0
10078: 00078863 beqz a5,10088 <register_fini+0x14>
1007c: 00010537 lui a0,0x10
10080: 43850513 addi a0,a0,1080 # 10438 <__libc_fini_array>
10084: 3a00006f j 10424 <atexit> …Run Code Online (Sandbox Code Playgroud) 我不确定我问的问题是否正确,但我想知道 C 或 ASM 程序是否可以在虚拟地址 0x0 处写入?
我知道内核不允许在虚拟 0x0 处写入/读取,但我想知道是否有一些奇怪的方法可以做到这一点。可能使用我不知道的 ld 或 gcc 标志?
设置如下:
操作系统从磁盘读取的内容多于程序实际请求的内容,因为程序将来可能需要附近的信息.在我的应用程序中,当我从磁盘中获取项目时,我想显示元素周围的信息间隔.我要求和显示的信息量和速度之间存在权衡.但是,由于操作系统已经读取了超过我的请求,因此访问内存中的这些字节是免费的.我可以使用什么API来找出操作系统缓存中的内容?
或者,我可以使用内存映射文件.在这种情况下,问题减少到找出页面是否交换到磁盘.这可以在任何常见的操作系统中完成吗?
编辑:相关论文http://www.azulsystems.com/events/mspc_2008/2008_MSPC.pdf
众所周知,在32位Windows操作系统下运行的程序只有2GB的可用虚拟内存.另外,已知其他2GB被保留为内核空间.但是那个内核空间究竟是什么呢?
我可以理解内核本身所需的保留,但为什么进程的VAS中的内核空间呢?谢谢.
这很好
int GB = 2;
int bytes = GB * 1024 * 1024 * 1024;
LPVOID memory = VirtualAlloc(
0,
bytes-1, // 2GB - 1
MEM_COMMIT,
PAGE_READWRITE);
Run Code Online (Sandbox Code Playgroud)
在这里,一旦达到2GB,就会失败
int GB = 2;
int bytes = GB * 1024 * 1024 * 1024;
LPVOID memory = VirtualAlloc(
0,
bytes, // 2GB
MEM_COMMIT,
PAGE_READWRITE);
Run Code Online (Sandbox Code Playgroud)
Windows错误消息"参数不正确".为什么会这样?实际上我想分配更多的虚拟内存.
Linux为每个要使用的程序创建虚拟内存页面,操作系统处理将虚拟地址映射到真正的硬件地址,对吗?
但Windows如何做到这一点?Windows程序实际上是否具有转换为真实硬件地址的内存?我也知道当RAM过度使用时,windows可以使用硬盘内存,而这个过程又被称为虚拟内存,但我相信这是一个完全不同的概念?
virtual-memory ×10
linux ×5
c ×3
linux-kernel ×3
windows ×3
page-tables ×2
assembly ×1
elf ×1
emulation ×1
gcc ×1
kernel ×1
ld ×1
mmap ×1
mmu ×1
pagefile ×1
performance ×1
riscv ×1
winapi ×1