Memory Map (x86)

本文详细介绍了计算机在BIOS跳转到引导加载程序代码时刻的物理内存内容,包括低内存区域(小于1MiB)、高内存区域(大于1MiB)等关键信息,并讨论了这些区域的具体用途。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

This article describes the contents of the computer's physical memory at the moment that the BIOS jumps to your bootloader code.

Contents

[hide]

< type="text/javascript"> if (window.showTocToggle) { var tocShowText = "show"; var tocHideText = "hide"; showTocToggle(); }

"Low" memory (< 1 MiB)

When a typical x86 PC boots it will be in Real Mode, with an active BIOS. During the time the CPU remains in Real Mode, IRQ0 (the clock) will fire repeatedly, and the hardware that is used to boot the PC (floppy, hard disk, CD, Network card, USB) will also generate IRQs. This means that during the PC boot process, the Real Mode IVT (see below) must be carefully preserved, because it is being used.

When the IVT is activated by an IRQ, it will call a BIOS routine to handle the IRQ. Bootloaders will also access BIOS functions. This means that the two memory workspaces that the BIOS uses (the BDA and the EBDA) must also be carefully preserved during boot. Also, every time the BIOS handles an IRQ0 (18 times a second), several bytes in the BDA get overwritten by the BIOS -- so do not attempt to store anything there while IRQs are active in Real Mode.

After all the BIOS functions have been called, and your kernel is loaded into memory somewhere, the bootloader or kernel may exit Real Mode forever (often by going into 32bit Protected Mode). If the kernel never uses Real Mode again, then the first 0x500 bytes of memory in the PC may be reused and overwritten. (However, it is very common to temporarily return to Real Mode in order to change the Video Display Mode.)

When the CPU is in Protected Mode, System Management Mode (SMM) is still invisibly active, and cannot be shut off. SMM also seems to use the EBDA. So the EBDA memory area should never be overwritten.

Note: the EBDA is a variable-sized memory area (on different BIOSes). If it exists, it is always immediately below 0xA0000 in memory. It is absolutely guaranteed to be less than 128 KiB in size. It is often 1 KiB. The biggest ones ever actually seen are 8 KiB. You can determine the size of the EBDA by using BIOS function INT 12h, or (often) by examining the word at 0x40E in the BDA (see below). Both of those methods will tell you the location of the bottom of the EBDA.

It should also be noted that your bootloader code is probably loaded and running in memory at physical addresses 0x7C00 through 0x7DFF. So that memory area is likely to also be unusable until execution has been transferred to a second stage bootloader, or to your kernel.

Overview

(all values except KiBs are in hex)

start end size type description
Low Memory (the first MiB)
00000000 000003FF 400 (1 KiB) RAM - partially unusable (see above) Real Mode IVT (Interrupt Vector Table)
00000400 000004FF 100 RAM - partially unusable (see above) BDA (BIOS data area)
00000500 00007BFF 7700 (almost 30 KiB) RAM (guaranteed free for use) Conventional memory
00007C00 (typical location) 00007DFF 200 RAM - partially unusable (see above) Your OS BootSector
00007E00 0007FFFF 7FB00 (481 KiB) RAM (guaranteed free for use) Conventional memory
00080000 0009FBFF 1FC00 (approximately 120 KiB) RAM (free for use, if it exists) Conventional memory
0009FC00 (typical location) 0009FFFF 400 RAM (unusable) EBDA (Extended BIOS Data Area)
000A0000 000FFFFF 60000 various (unusable) ROM Area (384 KiB)

 

BIOS Data Area (BDA)

The BDA is only partially standardized, and almost all the values stored there are completely obsolete and uninteresting. The following is a partial list. See the External Links references below for more detail.

address (size) description
400 (word) IO port for COM1 serial
408 (word) IO port for LPT1 parallel
40E (word) EBDA base address >> 4 (usually!)
410 (word) packed bit flags for detected hardware
449 (byte) Display Mode
463 (2 bytes, taken as a word) base IO port for video
46C (word) # of IRQ0 timer ticks since boot
475 (byte) # of hard disk drives detected
497 (byte) last keyboard LED/Shift key state

 

Extended BIOS Data Area (EBDA)

You may see "maps" of the EBDA if you search the web. However, those maps are for the original IBM BIOS EBDA. They do not apply to any current EBDA, used by any current BIOS. The EBDA area is not standardized. It does contain data that your OS will need, but you must do a bytewise pattern search to find those tables. (See PlugNPlay.)

 

ROM Area

start end size region/exception description
Standard usage of the ROM Area
000A0000 000AFFFF 10000 video RAM VGA framebuffer (64 KiB)
000B0000 000B7FFF 8000 video RAM VGA text monochrome (32 KiB)
000B8000 000BFFFF 8000 video RAM VGA text color (32 KiB)
000C0000 000C7FFF 8000 ROM Video BIOS (32 KiB is typical size)
000C8000 000EFFFF 28000 ROMs and unusable space Mapped hardware & Misc.
000F0000 000FFFFF 10000 ROM Motherboard BIOS (64 KiB is typical size)

 

"Upper" Memory (> 1 MiB)

The region of RAM above 1 MiB is not standardized, well-defined, or contiguous. There are likely to be regions of it that contain memory mapped hardware, that nothing but a device driver should ever access. There are likely to be regions of it that contain ACPI tables which your initialization code will probably want to read, and that then can be overwritten and reused. Some ACPI areas cannot be "reclaimed" this way. Some of the computer's RAM may extend above 4 GiB.

Use the BIOS function INT 15h, EAX=0xE820 to get a reliable map of Upper Memory.

 

start end size region/exception description
High Memory
00100000 003FFFFF 00300000 RAM -- guaranteed free for use1 Extended memory
00400000 00EFFFFF 00900000 (if it all exists) RAM -- free for use Extended memory
00F00000 00FFFFFF 100000 Possible memory mapped hardware ISA Memory Hole 15-16MB (only with ISA bus?)
01000000  ????????  ???????? (whatever exists) RAM -- free for use More Extended memory
C000000 (sometimes) FFFFFFF 4000000 various (unusable except by drivers) PnP NVRAM?, LAPIC, BIOS, ...
10000000 (possible mem above 4 GiB)  ????????  ???????? (whatever exists) RAM -- free for use (PAE/64bit) More Extended memory

1: Free for use except that your bootloader (ie. GRUB) may have loaded your "modules" here, and you don't want to overwrite those.

 

Comments

See Also

External Links

<think>好的,用户想了解如何让GCC生成map文件以及如何解析其中的信息。首先,我需要回忆一下之前提供的步骤和相关引用,确保回答准确。 用户之前的问题是关于用grep查找map文件中的标准库引用,现在他转向如何生成和解析map文件。根据之前的引用,比如引用[3]和[5]提到使用-Wl,-Map参数来生成map文件。所以生成方法应该包括在编译命令中加入这个选项。 生成map文件的方法可能包括基本命令和进阶选项,比如添加详细符号信息或者交叉引用。需要分步骤说明,确保用户能跟着操作。 解析map文件的部分,用户需要知道如何查找关键信息,如内存分布、符号表、库依赖等。之前回答中用了grep命令来筛选内容,这里可以延续类似的方法,指导用户如何定位重要部分。 另外,用户可能关心map文件的结构,比如各个部分的含义,如内存段、符号地址、库引用等。需要结合引用[1]中的内容,解释map文件的结构,帮助用户理解各部分的作用。 可能的问题包括生成map文件的不同参数选项,或者解析时的常见问题。需要确保回答覆盖这些点,并提供相关的示例命令,如使用grep或结合readelf工具。 还要注意用户可能的应用场景,比如调试或优化程序内存使用,因此需要强调这些解析步骤的实际用途。例如,查看内存分布有助于优化内存分配,检查符号冲突可以解决链接错误。 最后,确保引用正确的来源,比如引用[3]和[5]关于生成map文件的方法,引用[1]关于map文件的结构,引用[4]的例子中的编译命令。保持回答结构清晰,分步骤说明,并附上相关问题,帮助用户深入理解。</think>根据GCC编译器的工作机制和.map文件的结构特性,我将分步骤说明生成和解析.map文件的具体方法: ### 一、生成.map文件 #### 1. 基础生成方法 ```bash gcc -o myprog source.c -Wl,-Map=output.map ``` 通过`-Wl`参数向链接器传递`-Map=文件名`指令,这是生成.map文件的核心参数[^3][^5] #### 2. 进阶生成方法 ```bash gcc -o myprog src/*.c -Wl,-Map=detail.map,-cref,-print-memory-usage ``` * `-cref`:生成交叉引用表 * `-print-memory-usage`:显示内存使用统计 * 添加`-ffunction-sections -fdata-sections`可获取更详细的段信息[^1] #### 3. 调试增强版 ```bash gcc -g -Wa,-adhln=asm.lst -Wl,-Map=debug.map,-cref source.c ``` 同时生成汇编列表文件(.lst)和带调试符号的.map文件[^2] ### 二、解析.map文件 .map文件通常包含以下核心结构: ``` Memory Configuration <-- 内存区域定义 Linker script and memory map <-- 关键内存分布 Allocating common symbols <-- 公共符号分配 Discarded input sections <-- 被丢弃的段 Cross Reference Table <-- 符号交叉引用[^1] ``` #### 关键解析步骤: 1. **查看内存分布** ```bash grep -A 20 "Memory Configuration" output.map ``` 显示代码/数据段的起始地址和大小,例如: ``` .text 0x0000000000401000 0x1500 .data 0x0000000000403000 0x400 ``` 2. **提取符号表** ```bash grep -E '^0x[0-9a-f]+\s+\S+' output.map | sort -k 1 ``` 按地址排序显示所有符号,输出示例: ``` 0x0000000000401120 main 0x0000000000401150 printf@plt ``` 3. **分析库依赖** ```bash grep 'LOAD.*/usr/lib' output.map | awk '{print $3}' ``` 显示链接的共享库路径,如: ``` /lib/x86_64-linux-gnu/libc.so.6 /lib64/ld-linux-x86-64.so.2 ``` 4. **检查符号冲突** ```bash grep 'multiple definition' output.map -C 3 ``` 检测多定义的全局符号,这类错误会导致链接失败 5. **计算段使用率** ```bash awk '/Memory region/ {flag=1} /=======/ {flag=0} flag' output.map ``` 显示各内存区域的使用统计: ``` region size used available FLASH: 256 KB 152 KB 104 KB RAM: 64 KB 58.2 KB 5.8 KB ``` ### 三、典型应用场景 1. **调试内存溢出**:通过`.bss`段大小判断静态变量占用 2. **优化程序体积**:识别占用大的目标文件(如`libm.a`中的数学函数) 3. **分析启动过程**:查找`_start`符号确定程序入口地址[^4] 4. **检查链接顺序**:查看库加载顺序对符号解析的影响
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值