【问题标题】:Why does the general program usually start at 0x8000?为什么一般程序一般都是从0x8000开始?
【发布时间】:2012-03-29 13:51:43
【问题描述】:

我对bootloader和system SW并不陌生,但是不知道一般程序为什么从0x8000开始的原因。我已经知道地址 0x8000 已被用作普通 C/C++ 程序中的起始地址。

一般程序的引导加载程序的最小大小是否达到0x8000?或者应该分配给引导加载程序的 ROM 的最小块大小是 32KB?还是有其他原因?

我想从历史或逻辑上以及从虚拟地址的角度了解这一点。


感谢您在这方面的时间和帮助。 为了让问题更清楚,这个问题与虚拟地址有关,而不是与物理地址有关。

从物理内存地址的角度来看,我基本同意R的观点。

不说具体的系统是否多样化,例如linux(甚至在android中),通用RTOS(nucleus等,尤其是ARM链接器部分),它们都使用地址0x8000作为起始地址通用程序。 如crt_begin.o、crt.o等,位于0x0,带loader的区域存在。

因此,如果在启动时(冷启动)位于 BootROM 中,考虑到块大小,我猜一般程序的引导加载程序的最小大小为 32KB。

嗯,但我不确定……

【问题讨论】:

  • 你在说什么系统?
  • 我没有任何可靠的来源,但我可以做出一个合格的猜测。从历史上看,许多处理器,尤其是 8 位处理器,都具有称为 zero page 的功能,这意味着地址 0x00 - 0xFF 的内存单元具有指令支持以更快地执行。我相信这是摩托罗拉在过去引入的,因为他们在 6800 等旧 MCU 上具有内存映射 I/O 寄存器。->
  • 因此,您希望内存的第一个区域被 RAM 单元或特殊寄存器占用。然后,零页之后的地址空间部分具有相同的性质是有道理的:RAM 和/或寄存器。这将占用大量 kb,可能高达 0x6000 或类似的。然后我假设将 ROM(程序存储器)放在偶数地址很方便,而 0x8000 很方便。我相当肯定这个问题的答案可以在早期的摩托罗拉处理器设计中找到。
  • 这可能是相关的:en.wikipedia.org/wiki/ELF_binary。也许大小是为了与以前的格式兼容?

标签: c++ c linker bootloader


【解决方案1】:

一般来说,除了最小的嵌入式系统之外,平台 ABI 设计人员希望避免使用最低地址,以便可以捕获空指针取消引用。如果使用数组或结构成员偏移量取消引用空指针(如null_ptr->some_member),则拥有几 KB 的永不有效地址可为您提供一些额外的安全性。

【讨论】:

  • 我不相信这是原因,我曾使用过几个嵌入式系统,其中地址 0 是有效且可寻址的内存,同时 NVM 从 8000 开始。
  • ...特别是因为地址 0x8000 在 C 语言和 NULL 指针流行之前就已经存在。也许甚至在 C 被发明之前?
  • @MSalters malloc() 如果失败则返回一个空指针。不要求空指针是地址 0(只要计算为 0 的整数常量隐式转换为它,无论它是什么)。而系统将中断处理程序之类的东西放在哪里取决于硬件——英特尔一直将它们放在最开始,但其他系统各不相同。
  • @JamesKanze:当然,但是“硬件可以接受”的“嵌入式系统”是没有虚拟机的简单系统(如果你有虚拟机,你就不要映射(void*)NULL在过程空间中)。在这些系统上,您非常接近金属,以至于您真的希望NULL 按位为 0。是的,中断处理程序就是一个例子;其他 CPU 的内存映射 I/O 寄存器位于地址 0。
  • @MSalters 对于VM,最简单的解决方案是不映射地址0,使用0作为空指针常量。没有虚拟机,系统会使用各种各样的东西,而且肯定会有空指针不是地址 0 的系统。
【解决方案2】:

取决于系统,程序从不同的地址开始 不同的系统。在 Unix 下,这是通常的(或者甚至可能需要 Posix) 使用地址 0 作为空指针,并且不映射 虚拟内存的第一页,因此取消引用空指针将 导致段违规。我怀疑其他系统使用 地址 0 作为空指针的行为类似(但它们保留了多少 可能会有所不同)。 (从历史上看,通常将第一页映射为已读 只有,并用零填充,空指针的行为就像 它是一个空字符串,一个指向"" 的指针。回到大约 25 年。)

我希望即使在今天,一些嵌入式系统也会加载 程序从地址 0 开始。

【讨论】:

    【解决方案3】:

    这有点随意,在 linux 上,至少由链接器决定。总体思路是预留一些空间来捕获 NULL 指针异常。为了帮助防止内核空间 NULL 指针取消引用在内核模式下执行任意用户代码,linux 会阻止您映射内存的最底部。 /proc/sys/vm/mmap_min_addr 控制您可以映射的最低地址(如果您愿意,可以将其更改为 0 并将页面映射到 0)。

    在 linux 上,您可以通过查看/proc 来查看内存映射。例如,

    genwitt ~> cat /proc/self/maps
    00400000-0040c000 r-xp 00000000 08:01 354804 /bin/cat
    0060b000-0060c000 r--p 0000b000 08:01 354804 /bin/cat
    0060c000-0060d000 rw-p 0000c000 08:01 354804 /bin/cat
    01dda000-01dfb000 rw-p 00000000 00:00 0 [堆]
    7f5b25913000-7f5b25a97000 r-xp 00000000 08:01 435953 /lib64/libc-2.14.1.so
    7f5b25a97000-7f5b25c97000 ---p 00184000 08:01 435953 /lib64/libc-2.14.1.so
    7f5b25c97000-7f5b25c9b000 r--p 00184000 08:01 435953 /lib64/libc-2.14.1.so
    7f5b25c9b000-7f5b25c9c000 rw-p 00188000 08:01 435953 /lib64/libc-2.14.1.so
    7f5b25c9c000-7f5b25ca1000 rw-p 00000000 00:00 0
    7f5b25ca1000-7f5b25cc2000 r-xp 00000000 08:01 436061 /lib64/ld-2.14.1.so
    7f5b25cd2000-7f5b25e97000 r--p 00000000 08:01 126248 /usr/lib64/locale/locale-archive
    7f5b25e97000-7f5b25e9a000 rw-p 00000000 00:00 0
    7f5b25ec0000-7f5b25ec1000 rw-p 00000000 00:00 0
    7f5b25ec1000-7f5b25ec2000 r--p 00020000 08:01 436061 /lib64/ld-2.14.1.so
    7f5b25ec2000-7f5b25ec3000 rw-p 00021000 08:01 436061 /lib64/ld-2.14.1.so
    7f5b25ec3000-7f5b25ec4000 rw-p 00000000 00:00 0
    7fff18c37000-7fff18c58000 rw-p 00000000 00:00 0 [堆栈]
    7fff18d0c000-7fff18d0d000 r-xp 00000000 00:00 0 [vdso]
    ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]

    【讨论】:

      【解决方案4】:

      我怀疑在很多情况下,前 32K 是为监视器代码/内存使用而保留的。在许多 8051 评估板中,所有应用默认为 0x1000 或 0x2000 的情况并不少见,具体取决于常驻监视器(一些也用作调试器)。

      32K 可能是您的 u-boot/etc 加载程序空间。

      【讨论】:

        【解决方案5】:

        我相信答案更多地与中断处理有关。中断处理程序地址在硬件中设置。在 Intel 8086 中,有一个关于中断处理程序代码和相应中断处理例程的直接转换表。可能,这是由一些组合电路完成的,因此,为了保持前向兼容性,将它们放在内存的开头而不是末尾以防止每次都发生变化会更明智。因此,执行起始地址将位于内存的另一端。此外,该块中必须包含足够的代码来加载内存段程序和跳转指令以切换到从该代码地址执行代码。

        【讨论】:

          猜你喜欢
          • 2012-12-15
          • 1970-01-01
          • 2014-10-05
          • 2012-04-29
          • 2022-08-19
          • 1970-01-01
          • 1970-01-01
          • 2017-10-19
          • 2011-01-15
          相关资源
          最近更新 更多