电子产业一站式赋能平台

PCB联盟网

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

Linux物理地址和虚拟地址

[复制链接]

649

主题

649

帖子

4484

积分

四级会员

Rank: 4

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

va2mclgvhgp64022998228.gif

va2mclgvhgp64022998228.gif
+ \& ~: {6 K2 d! e" a, M+ L
点击上方蓝色字体,关注我们
5 o6 U( |1 Q/ ]9 R! F8 a  T
4 m6 i$ p5 i' S) h" A& {) U) i5 aMMU 通过页表将虚拟地址转换为物理地址,页表保存了虚拟地址到物理地址的映射信息。不同的进程可以有相同的虚拟地址,但它们映射到的物理地址可能不同。' F8 K- E; x$ G

4 w. o$ }: P6 L* R- t
  • 页 (Page): 虚拟内存和物理内存被划分为相同大小的块,称为页。1 i1 q' [; \2 L, E- Y
    常见的页大小为 4 KB。
  • 页表 (Page Table): 页表是一个数据结构,存储了虚拟地址与物理地址的映射。6 g5 l0 _- q! g" R1 \" m# {
    8 x& C% ?8 Q7 S3 U( `
    页表示例:. w$ K* H4 {4 ^& ?; h6 V" H! e! \8 L
    假设有一个虚拟地址 0xB8000000,通过页表,它可能被映射到物理地址 0x12000000。这个过程是透明的,应用程序只需要处理虚拟地址,操作系统和硬件负责完成地址转换。
    8 ?- b7 m$ m  O4
    5 q+ B) x* y; }+ M1 `9 ]虚拟地址的应用实例( g. H: J9 E; b8 Z2 E( c6 o, Y
    在应用程序中,开发人员通常只与虚拟地址打交道。以下是一个简单的 C 程序示例,演示如何使用虚拟地址访问内存。. ]. ?; O1 B" S% |: @! _) Z
    ) j& r) G& Q  l3 H. }1 v! W  Z
  • #include #include  int main() {    int *ptr = (int *)malloc(sizeof(int));    if (ptr == NULL) {        fprintf(stderr, "内存分配失败!
    ' d; {4 O) y) W! n7 `' c; @- Y, J");        return 1;    }     *ptr = 42;    printf("虚拟地址: %p, 值: %d
    + p6 N) s5 M( ]2 [7 y4 V% \# q", (void*)ptr, *ptr);     free(ptr);    return 0;}3 P2 h0 q3 Z, h0 y; d
    在这个示例中,malloc() 函数分配了一块内存,并返回该内存块的虚拟地址。该地址在程序的虚拟地址空间中有效,指向一个内存位置。通过打印指针 ptr 的值,可以看到虚拟地址。
    * e* `2 J& _3 `* n0 ~# k0 D51 A' m' E! {+ N: M0 v
    物理地址的应用实例
    / v+ K" m: Q8 l3 m0 w3 N5 |物理地址的直接使用通常仅限于操作系统内核或驱动程序开发。在内核编程中,开发人员可以通过一些内核 API 来获取物理地址。例如,通过 virt_to_phys() 函数可以将虚拟地址转换为物理地址。. Q' l. E7 M! ~7 \

    - M7 z# F$ e: W
  • #include #include #include  int init_module(void) {    void *vaddr;    unsigned long paddr;     vaddr = kmalloc(4096, GFP_KERNEL);    if (!vaddr) {        printk("内存分配失败/ s% R: \+ H7 J7 M0 X
    ");        return -ENOMEM;    }     paddr = virt_to_phys(vaddr);    printk("虚拟地址: %p, 物理地址: %lx2 ~7 V. T/ g. y& g, ~8 b$ h8 S
    ", vaddr, paddr);     kfree(vaddr);    return 0;} void cleanup_module(void) {    printk("模块卸载! p2 g) k3 [8 p& A- c
    ");} MODULE_LICENSE("GPL");9 _4 Q1 |5 E5 g6 g' S
    这个内核模块分配了一块内存,并将其虚拟地址转换为物理地址。virt_to_phys() 函数只在内核态有效,用户态程序无法直接调用。) ?: t  i% K$ W( A
    68 G3 ~1 a0 w( A; k% Z$ J

    ! f$ F3 c9 S  W. `1 b( a4 P物理地址和虚拟地址的优缺点  ]4 z2 ^, e# @7 B
    虚拟地址的优点+ t' B% G, R& h/ c2 }
  • 每个进程拥有独立的虚拟地址空间,提高了安全性和稳定性。
  • 虚拟地址空间可以大于实际物理内存,通过交换技术(paging),虚拟内存可以被分配给更大的地址空间。' d5 {& |3 B& x

    + q9 |, F5 Q: s( j( x物理地址的优点$ c7 n" @: Y! g$ _
  • 直接对应物理内存,访问速度快,无需经过地址转换。
  • 在操作系统内核和驱动程序中,物理地址通常用于直接访问硬件资源。
    3 X. D) a2 ]) a/ x
    5 l% d* _, C' r+ p
    物理地址和虚拟地址是 Linux 系统内存管理的重要概念。虚拟地址提供了更灵活和安全的内存管理方式,使得每个进程拥有独立的地址空间。而物理地址则直接映射到实际的内存位置,通常用于内核级别的操作。理解这两个概念及其应用,对于系统编程和操作系统的深入理解非常关键。  O, e& B( k( ]1 ^0 u0 g/ Q

    eftvajl3jfr64022998328.jpg

    eftvajl3jfr64022998328.jpg
    ; |& R* \3 W9 v5 M; o7 n

    gkgfbkpow1q64022998428.gif

    gkgfbkpow1q64022998428.gif
    ! g5 C7 N1 `1 I( z! S! x
    点击阅读原文,更精彩~
  • 回复

    使用道具 举报

    发表回复

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

    本版积分规则


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