电子产业一站式赋能平台

PCB联盟网

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

Linux物理地址和虚拟地址

[复制链接]

649

主题

649

帖子

4484

积分

四级会员

Rank: 4

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

titkt03i1en6401182707.gif

titkt03i1en6401182707.gif

& {. P9 S) Q, o- r点击上方蓝色字体,关注我们
: v" e+ @6 o# @
) K! a9 J2 f8 ?/ h) L/ ~MMU 通过页表将虚拟地址转换为物理地址,页表保存了虚拟地址到物理地址的映射信息。不同的进程可以有相同的虚拟地址,但它们映射到的物理地址可能不同。
* ]- v7 t5 J  M: W) F
- N7 q( u8 e# o* R& R
  • 页 (Page): 虚拟内存和物理内存被划分为相同大小的块,称为页。
    % |3 T- m* y- F) N- U6 p常见的页大小为 4 KB。
  • 页表 (Page Table): 页表是一个数据结构,存储了虚拟地址与物理地址的映射。- k, J8 K6 I3 _$ S6 ~& Q* e( {
    " x! Q0 [1 h" c4 B0 Y' u2 Y
    页表示例:) i& b' n& H9 M! a
    假设有一个虚拟地址 0xB8000000,通过页表,它可能被映射到物理地址 0x12000000。这个过程是透明的,应用程序只需要处理虚拟地址,操作系统和硬件负责完成地址转换。8 ^  {+ E6 W* T; j9 Q
    4+ s; w8 U7 y3 T* r
    虚拟地址的应用实例% q6 ~% {& c% Q* n/ U, ~- V7 @
    在应用程序中,开发人员通常只与虚拟地址打交道。以下是一个简单的 C 程序示例,演示如何使用虚拟地址访问内存。
    " W% e0 ?/ I/ F% [9 i* _# O2 f& u
  • #include #include  int main() {    int *ptr = (int *)malloc(sizeof(int));    if (ptr == NULL) {        fprintf(stderr, "内存分配失败!2 S! K) m. F9 F. M
    ");        return 1;    }     *ptr = 42;    printf("虚拟地址: %p, 值: %d
    % d' [. h0 y2 V- \. C", (void*)ptr, *ptr);     free(ptr);    return 0;}
    . _  v- z( n/ D; |在这个示例中,malloc() 函数分配了一块内存,并返回该内存块的虚拟地址。该地址在程序的虚拟地址空间中有效,指向一个内存位置。通过打印指针 ptr 的值,可以看到虚拟地址。* c5 U/ b; j' J$ _
    5
    - T/ I, L' y  t% W( U物理地址的应用实例
    ' r! E2 k9 i3 J6 G0 k7 K4 d) B+ T物理地址的直接使用通常仅限于操作系统内核或驱动程序开发。在内核编程中,开发人员可以通过一些内核 API 来获取物理地址。例如,通过 virt_to_phys() 函数可以将虚拟地址转换为物理地址。: x* D( Z3 f1 \- }* e1 U
      t& Q4 q/ l% ^1 Q, Y
  • #include #include #include  int init_module(void) {    void *vaddr;    unsigned long paddr;     vaddr = kmalloc(4096, GFP_KERNEL);    if (!vaddr) {        printk("内存分配失败
    + q6 N" E/ B2 d) a");        return -ENOMEM;    }     paddr = virt_to_phys(vaddr);    printk("虚拟地址: %p, 物理地址: %lx
    $ b9 s2 [% H9 q  h", vaddr, paddr);     kfree(vaddr);    return 0;} void cleanup_module(void) {    printk("模块卸载
    / ~" w# [1 _; M1 o& b8 X; N");} MODULE_LICENSE("GPL");
    ) j9 o* U* e! C0 M这个内核模块分配了一块内存,并将其虚拟地址转换为物理地址。virt_to_phys() 函数只在内核态有效,用户态程序无法直接调用。8 c% M5 J* U4 j; m
    6
    ' E+ L/ G3 z  _* K
    0 S% X9 j/ h# n1 P& M3 X6 ]物理地址和虚拟地址的优缺点
    & }3 J  p7 }  g虚拟地址的优点1 j8 F, i* u- w/ H9 {. w3 _
  • 每个进程拥有独立的虚拟地址空间,提高了安全性和稳定性。
  • 虚拟地址空间可以大于实际物理内存,通过交换技术(paging),虚拟内存可以被分配给更大的地址空间。
    1 R0 p4 T; A9 d6 P4 g" x
    0 ^: \8 I1 T# k
    物理地址的优点; |# O8 J# n5 V" P1 m3 b0 A
  • 直接对应物理内存,访问速度快,无需经过地址转换。
  • 在操作系统内核和驱动程序中,物理地址通常用于直接访问硬件资源。
    " N' u: T; c8 U& O
    + h% `  Q( k6 s: O! l! S
    物理地址和虚拟地址是 Linux 系统内存管理的重要概念。虚拟地址提供了更灵活和安全的内存管理方式,使得每个进程拥有独立的地址空间。而物理地址则直接映射到实际的内存位置,通常用于内核级别的操作。理解这两个概念及其应用,对于系统编程和操作系统的深入理解非常关键。
    : C, ~0 a/ d, {: g

    a2i1j1mphfu6401182807.jpg

    a2i1j1mphfu6401182807.jpg

    7 R9 a/ D2 l+ j- ~; B+ K- e# y

    jdt3w00ayuw6401182907.gif

    jdt3w00ayuw6401182907.gif
    " M" }: K* z/ r. Y9 X/ B
    点击阅读原文,更精彩~
  • 回复

    使用道具 举报

    发表回复

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

    本版积分规则


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