是加载地址是在Linux中所有的C程序中常用的? [英] Are the load address is common for all the C programs in linux?

查看:176
本文介绍了是加载地址是在Linux中所有的C程序中常用的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

让我们说我有一个prog1.c的是建设成为prog1.out。在prog1.out有一个连接器的信息,这可以告诉那里的精灵将被载入。这些地址将是一个虚拟地址。装载机将寻找这些信息的和发射这是一个过程。像DS,BSS每一节都将在虚拟地址在链接中提到加载。例如,我有prog2.out也有相同的装载机地址,BSS,DS等那么它会发生冲突?我知道这不会发生冲突,但随后会有性能问题。由于这两个过程具有相同的虚拟地址,但它们映射到不同的物理地址?我很困惑,怎么能保护具有相同的虚拟地址的两个过程。

Let's say I have a prog1.c which is build as prog1.out. In prog1.out there is a linker information that will tell where the elf will be loaded. These addresses will be a virtual addresses. The loader will look for these information's and a launch this as a process. Each section like DS,BSS will be loaded on the virtual address as mentioned in the linker. For example, I have prog2.out that also have the same loader address, BSS, DS,etc then will it conflict? I know it will not conflict but then will there be a performance issue. Since the two process have the same virtual address but they map to different physical addresses? I am confused, how it can protect the two processes having the same virtual addresses.

推荐答案

的事情是,当一个进程使用一个内存地址,它是在谈论一个虚拟地址,这可能是相同的物理地址相同。这意味着,两种工艺可参考同一地址和不混合它们的数据,因为这将是在两个不同的物理位置。

The thing is that when a process uses a memory address, it is talking about a Virtual Address, which may be different to the same physical address. This means that two process can refer to the same Address and don't mix their data, because it will be in two different physical locations.

下面我描述了虚拟地址被如何转换为典型的计算机物理地址(这个数字的变动对其他架构一点,但它是相同的想法)

Below I describe how the virtual address gets converted to a physical address on typical computers (this varies a little on other architectures, but it's the same idea)

所以,一方面你有一个虚拟内存地址,并希望得到一个物理内存地址(即:在RAM中的实际地址),工作流程大多是这样的:

So, in one hand you have a Virtual Memory Address, and you want to get to a Physical Memory Address (i.e: The actual address on the RAM), the workflow is mostly this:

虚拟地址 - > [分割单位] - > [分页单元] - >物理地址

每个操作系统可以定义分段单元和分页的工作方式。 Linux为例,使用的平分割模型的,这意味着它被忽略,所以我们现在就这样做。

Each operating system may define the way the Segmentation Unit and Paging works. Linux, for example, uses a Flat Segmentation Model, which means that it is ignored, so we would do the same now.

现在,我们的虚拟地址进入低谷一些所谓的寻呼单位,并得到转换以某种方式为物理地址。这是怎么样。

Now, our virtual address goes trough something called Paging Unit, and gets converted to a physical address somehow.. This is how.

的内存在一定的尺寸块划分,英特尔这种规模可能是4KB或4MB。

The memory is divided in blocks of a certain size, on intel this size may be 4KB or 4MB.

每个过程定义了一组在内存中的表,以便计算机知道应该如何翻译的内存地址。这些表在一​​个分层的方式组织,实际上,你想要的内存地址来访问被分解的指标为这些表。

Each process defines a set of tables in memory so the computer knows how it should translate memory addresses. These tables are organized in a hierarchical way, and actually, the memory address you want to access gets decomposed in indexes for these tables.

我知道,这听起来令人困惑,但留在我要多说两句。您可以按照我的写作与此图像:

I know, it sounds confusing, but stay with me for a few more sentences. You can follow my writing with this image:

有是一个内部CPU寄存器名为 CR3 存储第一个表的基址(我们称这个表页目录,其作品中的每一个被称为页目录项)。当正在执行的过程中,其 CR3 加载(除其他事项外)。

There's an internal CPU register called CR3 which stores the base address of the first table (we shall call this table Page Directory, and each one of its entries are called Page Directory Entry). When a process is being executed, its CR3 is loaded (among other things).

所以,现在你要访问到,比方说,内存地址的 0x00C30404

So, now you want to access to, let's say, memory address 0x00C30404,

寻呼机说好吧,让我们的页目录基地,看上去就CR3寄存器,知道哪里是网页目录的基础上,让我们叫(页目录基)这个地址PDB。

The paging unit says "Ok, let's get the page directory base", looks on the CR3 register and knows where is the base of the page directory, let's call this address PDB (Page Directory Base).

现在,你想知道哪个目录条目,你应该使用。至于我之前说的,地址在一堆指标被分解。最-显著10位(22槽31),对应页目录..该指数在这种情况下, 0x00C30404
0000 0000 1100 0011 0000 0100 0000 0100 二进制,其最显著10位是:
0000 0000 11 0x3中。这意味着,我们要寻求第3页目录项。

Now you want to know which directory entry you should use.. As I said before, the address gets decomposed in a bunch of indexes. The most-significant 10 bits (bits 22 trough 31), corresponds to the index of the Page Directory.. In this case, 0x00C30404 is 0000 0000 1100 0011 0000 0100 0000 0100 in binary, and its most significant 10 bits are: 0000 0000 11 which is 0x3. This means that we want to seek the 3rd page directory entry.

请记住,这些表是分层的:每个网页目录条目有,除其他事项外,下表的地址,叫页表。 (此表可针对不同每个网页目录条目)。

Remember that these tables are hierarchical: each Page Directory Entry has, among other things, the address of the next table, called Page Table. (This table may be different for each Page Directory Entry).

所以,现在,我们得到了另一个表..我们的地址的下一个10位将告诉我们,我们将访问此表的索引(我们姑且称之为页表项)。

So now, we got another table.. The next 10 bits of our address will tell us which index of this table we shall access (let's call them Page Table Entries).

00 0011 0000 是未来10位,他们分别是多少:的0x30 。这意味着,我们必须获得30 页表项 ..

00 0011 0000 are the next 10 bits, and they are the number: 0x30. This means that we have to access to the 30th Page Table Entry..

和最后,页表项持有的所需的页框的偏移(记住,内存在4K块划分)。最后,我们的地址的最低显著12位,是这个内存的页框的偏移,请注意,在页框是一个实际的物理内存地址。

And Finally, this Page Table Entry holds the offset of the desired PAGE FRAME (remember that memory is divided in blocks of 4k). Finally, the least-significant 12 bits of our address, are the memory offset of this PAGE FRAME, note that the PAGE FRAME is an actual physical memory address.

这就是所谓的3级分页,64位(或PAE)这是非常相似的,但有分页多了一个层次。

This is called 3-level paging, on 64 bits (or with PAE) it's very similar but there's one more level of paging.

您可能会认为这是一个真正的无赖来获得所有这些内存访问只是为了获取一个变量。而这是真的。有在计算机中的机制,以避免所有这些步骤,在它是TLB中(表后备缓冲区),它存储完成的所有翻译的一个高速缓存中,因此它可以很容易地取存储器。

You may think that it is a real bummer to get all these memory accesses just to fetch a variable.. And it's true. There are mechanisms in the computer to avoid all these steps, on of it is the TLB (Table Lookaside Buffer), it stores a cache of all the translations done, so it can fetch memory easily.

此外,这些结构中的每一项都有关于权限的一些属性,如这是页写吗? 就是这个页面的可执行文件?

Also, each Entry of these structures has some properties regarding permissions, like "Is this page writable?" "is this page executable?".

所以,现在您了解内存分页是如何工作的,很容易掌握的Linux如何处理内存:

So, now that you understand how memory paging works, it is easy to grasp how Linux handles the memory:


  • 每个进程都有自己的CR3并在过程计划运行,cr3寄存器被载入。

  • 每个进程都有自己的虚拟空间(表可能不是完整的,一个进程可以启动,例如,在只有4KB的单页)。

  • 每个进程都有映射一些其他的网页(操作系统内存),所以当它被中断,中断处理程序开始于相同的任务,并处理该任务中的中断,执行需要code。


  • 您不必有所有的进程在同一时间内存,可以存储一些磁盘。

  • 您可以安全地隔离每个进程的内存,并给它一些权限了。

  • 系统过程中可能使用的RAM 10MB的,但他们是在物理内存中连续的不是必需的。

(你喜欢我的解释?我是TA在计算机组织课程,并会喜欢一些反馈:P)

(Did you like my explanation?, I'm a TA at a Computer Organization course and would love some feedback :P)

这篇关于是加载地址是在Linux中所有的C程序中常用的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆