电子产业一站式赋能平台

PCB联盟网

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

Linux物理地址和虚拟地址

[复制链接]

649

主题

649

帖子

4484

积分

四级会员

Rank: 4

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

i51zjosep3r6409112714.gif

i51zjosep3r6409112714.gif

% \  [! f0 t8 H3 v% i& c  _* f点击上方蓝色字体,关注我们! L9 K; N) L2 w) q
- k/ i7 L' U, p4 Y6 r$ m
MMU 通过页表将虚拟地址转换为物理地址,页表保存了虚拟地址到物理地址的映射信息。不同的进程可以有相同的虚拟地址,但它们映射到的物理地址可能不同。
2 k. d% Z# x4 T
4 n1 ^/ F8 E: o
  • 页 (Page): 虚拟内存和物理内存被划分为相同大小的块,称为页。- c3 i' U* }2 N& O; N* I
    常见的页大小为 4 KB。
  • 页表 (Page Table): 页表是一个数据结构,存储了虚拟地址与物理地址的映射。
    / n1 Y% Y5 l, [5 W0 U

    # i. p! h$ Z8 Q2 |& ~! M  O3 R页表示例:. f& V6 q' A- {+ C
    假设有一个虚拟地址 0xB8000000,通过页表,它可能被映射到物理地址 0x12000000。这个过程是透明的,应用程序只需要处理虚拟地址,操作系统和硬件负责完成地址转换。
      k' k8 H* F/ R0 C& U7 m47 }3 a9 i. E& i& P1 a) _2 q
    虚拟地址的应用实例
    3 K6 Q- ?4 R" R  z. S在应用程序中,开发人员通常只与虚拟地址打交道。以下是一个简单的 C 程序示例,演示如何使用虚拟地址访问内存。0 C2 q5 t) V. T$ Q. L
    6 \6 c6 u  C3 I' Q: h
  • #include #include  int main() {    int *ptr = (int *)malloc(sizeof(int));    if (ptr == NULL) {        fprintf(stderr, "内存分配失败!# x3 _( ]5 M2 y5 e8 _
    ");        return 1;    }     *ptr = 42;    printf("虚拟地址: %p, 值: %d
    2 U5 f0 h+ \% y" Z  j$ ]1 y", (void*)ptr, *ptr);     free(ptr);    return 0;}; j. U5 A% n1 l
    在这个示例中,malloc() 函数分配了一块内存,并返回该内存块的虚拟地址。该地址在程序的虚拟地址空间中有效,指向一个内存位置。通过打印指针 ptr 的值,可以看到虚拟地址。! n7 \+ d2 j) |- g: e$ m( m8 |1 O8 X
    5
    & C$ V! Z1 O+ P% b7 D/ T0 N! t4 A物理地址的应用实例2 ^( ^  L" ?# g
    物理地址的直接使用通常仅限于操作系统内核或驱动程序开发。在内核编程中,开发人员可以通过一些内核 API 来获取物理地址。例如,通过 virt_to_phys() 函数可以将虚拟地址转换为物理地址。
    8 R: V3 R7 Y* k& m( Z! t. S. g) Q% y' k
  • #include #include #include  int init_module(void) {    void *vaddr;    unsigned long paddr;     vaddr = kmalloc(4096, GFP_KERNEL);    if (!vaddr) {        printk("内存分配失败' A5 n1 x( H7 t/ D
    ");        return -ENOMEM;    }     paddr = virt_to_phys(vaddr);    printk("虚拟地址: %p, 物理地址: %lx0 I% D) C6 j- L. I( R, C
    ", vaddr, paddr);     kfree(vaddr);    return 0;} void cleanup_module(void) {    printk("模块卸载2 c' }; F6 O7 ~  f0 n
    ");} MODULE_LICENSE("GPL");
    8 h7 ?+ c8 ?) U5 X* i' C这个内核模块分配了一块内存,并将其虚拟地址转换为物理地址。virt_to_phys() 函数只在内核态有效,用户态程序无法直接调用。& ]' l# G5 ^# X6 x4 V+ l! w
    6( I/ N$ T9 y5 s  {

    $ f. X/ f0 @) K; o5 ^物理地址和虚拟地址的优缺点1 t- h! A/ K6 [6 P+ g
    虚拟地址的优点. L. ]* v6 u" D8 R# |
  • 每个进程拥有独立的虚拟地址空间,提高了安全性和稳定性。
  • 虚拟地址空间可以大于实际物理内存,通过交换技术(paging),虚拟内存可以被分配给更大的地址空间。2 p* {! C& n* t  @2 n6 O' H- e

      ]' b; Q( [. M2 ?) F6 t8 S物理地址的优点. q- B# }8 s7 D4 u+ ]
  • 直接对应物理内存,访问速度快,无需经过地址转换。
  • 在操作系统内核和驱动程序中,物理地址通常用于直接访问硬件资源。
    ! V1 E0 T* f9 s; l  Y3 V6 g/ }
    " n, u+ i9 d- v4 ?9 a5 Q8 S' o
    物理地址和虚拟地址是 Linux 系统内存管理的重要概念。虚拟地址提供了更灵活和安全的内存管理方式,使得每个进程拥有独立的地址空间。而物理地址则直接映射到实际的内存位置,通常用于内核级别的操作。理解这两个概念及其应用,对于系统编程和操作系统的深入理解非常关键。
    ! Y$ A/ Y3 A* t6 r5 q. e% b

    2kwv2keq2cq6409112814.jpg

    2kwv2keq2cq6409112814.jpg
    ( z9 |0 |, W6 V; J0 S* o

    lgzs2kzcstp6409112914.gif

    lgzs2kzcstp6409112914.gif
    - n' L8 W5 V( k! J& Q
    点击阅读原文,更精彩~
  • 回复

    使用道具 举报

    发表回复

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

    本版积分规则


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