电子产业一站式赋能平台

PCB联盟网

搜索
查看: 109|回复: 0
收起左侧

Linux物理地址和虚拟地址

[复制链接]

649

主题

649

帖子

4484

积分

四级会员

Rank: 4

积分
4484
发表于 2024-9-14 12:03:00 | 显示全部楼层 |阅读模式

p0pnd4lijm36404577413.gif

p0pnd4lijm36404577413.gif

; \3 n' @! Q! Y1 B' \7 P6 Y3 {3 G点击上方蓝色字体,关注我们6 M' F8 B! X; q# G, @

' F$ ?/ u9 [" F. ^% c, j' E% }! cMMU 通过页表将虚拟地址转换为物理地址,页表保存了虚拟地址到物理地址的映射信息。不同的进程可以有相同的虚拟地址,但它们映射到的物理地址可能不同。
  v' O3 o7 P8 X' V8 l  l; @8 Q' y5 W) D( a$ K* i
  • 页 (Page): 虚拟内存和物理内存被划分为相同大小的块,称为页。
    / L" _, r8 u' z4 k4 D( ^# n常见的页大小为 4 KB。
  • 页表 (Page Table): 页表是一个数据结构,存储了虚拟地址与物理地址的映射。3 T+ _/ Q8 \4 e% o5 N  U5 s
    6 X/ {* R% A5 `6 Z; x2 P! j
    页表示例:6 y2 h) h( @! h: g3 n' S, J7 @1 X
    假设有一个虚拟地址 0xB8000000,通过页表,它可能被映射到物理地址 0x12000000。这个过程是透明的,应用程序只需要处理虚拟地址,操作系统和硬件负责完成地址转换。4 \; |/ `9 o' U
    4
    ) a  d' K3 n* y1 U$ t" D虚拟地址的应用实例6 Q- c. d4 N% w
    在应用程序中,开发人员通常只与虚拟地址打交道。以下是一个简单的 C 程序示例,演示如何使用虚拟地址访问内存。
    2 ~/ f; G/ u# V% I" ~' S- ?# ^8 y
  • #include #include  int main() {    int *ptr = (int *)malloc(sizeof(int));    if (ptr == NULL) {        fprintf(stderr, "内存分配失败!
    9 D# l  `% ^. T# p: ?& `8 U- _");        return 1;    }     *ptr = 42;    printf("虚拟地址: %p, 值: %d$ E4 @; N: ]* Y4 Q) U
    ", (void*)ptr, *ptr);     free(ptr);    return 0;}
    & o' T1 l2 G4 _在这个示例中,malloc() 函数分配了一块内存,并返回该内存块的虚拟地址。该地址在程序的虚拟地址空间中有效,指向一个内存位置。通过打印指针 ptr 的值,可以看到虚拟地址。
    % Z) e$ \. G, s3 `6 V$ V5
    3 i7 A$ ~7 v9 f( ?" B" {物理地址的应用实例9 C0 p% w  l7 |9 _
    物理地址的直接使用通常仅限于操作系统内核或驱动程序开发。在内核编程中,开发人员可以通过一些内核 API 来获取物理地址。例如,通过 virt_to_phys() 函数可以将虚拟地址转换为物理地址。
    9 j/ x! N5 m+ |2 J  {  L/ z. M
    $ z0 L6 j, k3 q3 @
  • #include #include #include  int init_module(void) {    void *vaddr;    unsigned long paddr;     vaddr = kmalloc(4096, GFP_KERNEL);    if (!vaddr) {        printk("内存分配失败
    ! i/ i4 ?) h  f" i  q, t");        return -ENOMEM;    }     paddr = virt_to_phys(vaddr);    printk("虚拟地址: %p, 物理地址: %lx
    ; d$ {3 O2 }: A! a5 P7 N. o1 m; ?  k", vaddr, paddr);     kfree(vaddr);    return 0;} void cleanup_module(void) {    printk("模块卸载
    : @7 H" g3 F+ @+ R. U0 Y1 s, C8 {");} MODULE_LICENSE("GPL");6 v6 F. V1 l+ k* |7 T6 a
    这个内核模块分配了一块内存,并将其虚拟地址转换为物理地址。virt_to_phys() 函数只在内核态有效,用户态程序无法直接调用。
    ; F3 T+ w" E, m7 X6% H# t6 H# s" L. N  F$ ]6 e: W
    7 I  K* q* i3 o+ n! X
    物理地址和虚拟地址的优缺点
    - V8 G. Y3 Y) O虚拟地址的优点
    * {2 x/ F, ?. |8 {1 L$ T( V
  • 每个进程拥有独立的虚拟地址空间,提高了安全性和稳定性。
  • 虚拟地址空间可以大于实际物理内存,通过交换技术(paging),虚拟内存可以被分配给更大的地址空间。
    . {* V$ C9 X  I; A! E" M
    5 E4 K# k& ~* U& b
    物理地址的优点
    7 F: S5 q, j( D" k3 {) o  A
  • 直接对应物理内存,访问速度快,无需经过地址转换。
  • 在操作系统内核和驱动程序中,物理地址通常用于直接访问硬件资源。1 d- n5 B- l+ e
    0 I3 u2 m4 R" b2 ~1 i* X+ M' G( j# Z
    物理地址和虚拟地址是 Linux 系统内存管理的重要概念。虚拟地址提供了更灵活和安全的内存管理方式,使得每个进程拥有独立的地址空间。而物理地址则直接映射到实际的内存位置,通常用于内核级别的操作。理解这两个概念及其应用,对于系统编程和操作系统的深入理解非常关键。6 o3 i  {. k. a0 {% k

    zbdyu5wn1p16404577513.jpg

    zbdyu5wn1p16404577513.jpg
    6 @; ^% x0 q& v" p$ b

    sofeaqo00p46404577613.gif

    sofeaqo00p46404577613.gif

    6 K6 F3 u# y$ P4 m6 t7 Z点击阅读原文,更精彩~
  • 回复

    使用道具 举报

    发表回复

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则


    联系客服 关注微信 下载APP 返回顶部 返回列表