Memory Map (x86)

本文详细描述了计算机在BIOS跳转到启动加载代码时物理内存的内容,包括低内存区域和高内存区域的分配与使用情况。

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

Memory Map (x86)

Revision as of 05:41, 22 May 2012 by  Amirsaniyan  (Talk | contribs)
( diff← Older revision | Latest revision (diff) | Newer revision → (diff)

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

Contents

 [hide

"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

startendsizetypedescription
Low Memory (the first MiB)
0x000000000x000003FF1 KiBRAM - partially unusable (see above)Real Mode IVT (Interrupt Vector Table)
0x000004000x000004FF256 bytesRAM - partially unusable (see above)BDA (BIOS data area)
0x000005000x00007BFFalmost 30 KiBRAM (guaranteed free for use)Conventional memory
0x00007C00 (typical location)0x00007DFF512 bytesRAM - partially unusable (see above)Your OS BootSector
0x00007E000x0007FFFF480.5 KiBRAM (guaranteed free for use)Conventional memory
0x000800000x0009FBFFapproximately 120 KiB, depending on EBDA sizeRAM (free for use, if it exists)Conventional memory
0x0009FC00 (typical location)0x0009FFFF1 KiBRAM (unusable)EBDA (Extended BIOS Data Area)
0x000A00000x000FFFFF384 KiBvarious (unusable)Video memory, ROM Area

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
0x0400 (4 words)IO ports for COM1-COM4 serial (each address is 1 word, zero if none)
0x0408 (3 words)IO ports for LPT1-LPT3 parallel (each address is 1 word, zero if none)
0x040E (word)EBDA base address >> 4 (usually!)
0x0410 (word)packed bit flags for detected hardware
0x0417 (word)keyboard state flags
0x041E (32 bytes)keyboard buffer
0x0449 (byte)Display Mode
0x044A (word)number of columns in text mode
0x0463 (2 bytes, taken as a word)base IO port for video
0x046C (word)# of IRQ0 timer ticks since boot
0x0475 (byte)# of hard disk drives detected
0x0480 (word)keyboard buffer start
0x0482 (word)keyboard buffer end
0x0497 (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. (SeePlug-and-Play.)

ROM Area

startendsizeregion/exceptiondescription
Standard usage of the ROM Area
0x000A00000x000BFFFF128 KiBvideo RAMVGA display memory
0x000C00000x000C7FFF32 KiB (typically)ROMVideo BIOS
0x000C80000x000EFFFF160 KiB (typically)ROMs and unusable spaceMapped hardware & Misc.
0x000F00000x000FFFFF64 KiBROMMotherboard BIOS

"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.


startendsizeregion/exceptiondescription
High Memory
0x001000000x00EFFFFF0x00E00000 (14 MiB)RAM -- free for use (if it exists)Extended memory 1, 2
0x00F000000x00FFFFFF0x00100000 (1 MiB)Possible memory mapped hardwareISA Memory Hole 15-16MB 3
0x01000000 ???????? ???????? (whatever exists)RAM -- free for useMore Extended memory 1
0xC0000000 (sometimes, depends on motherboard and devices)0xFFFFFFFF0x40000000 (1 GiB)various (typically reserved for memory mapped devices)Memory mapped PCI devices, PnP NVRAM?, IO APIC/s, local APIC/s, BIOS, ...
0x0000000100000000 (possible memory above 4 GiB) ???????????????? ???????????????? (whatever exists)RAM -- free for use (PAE/64bit)More Extended memory 1
 ???????????????? ???????????????? ????????????????Possible memory mapped hardwarePotentially usable for memory mapped PCI devices in modern hardware (but typically not, due to backward compatibility)

1: Different computers have different amounts of RAM, therefore the amount of extended memory you might find will vary and may be anything from "none" (e.g. an old 80386 system) to "lots".

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

3: The "ISA Memory Hole" (from 0x00F00000 to 0x00FFFFFF) was used for memory mapped ISA devices (e.g. video cards). Modern computers have no need for this hole, but some chipsets still support it (as an optional feature) and some motherboards may still allow it to be enabled with BIOS options, so it may exist in a modern computers with no ISA devices.



<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、付费专栏及课程。

余额充值