嵌入式linux開發 (三十五) 內存管理2.0(6) linux內存管理

這個概念有點大,先從用戶程序的段開始看吧
// 需要知道 用戶程序中的 (.code .rodata .data .bss .stack .heap) 在哪裏
// 需要知道 用戶程序中訪問的地址是虛擬地址還是物理地址

有一個工具 VMMap  待使用
- https://blog.csdn.net/qq_30025621/article/details/90207894

./aarch64/aarch64_addr
p_stack1:0x0000007feef5a760
p_stack2:0x0000007feef5a75c
p_heap1 :0x0000000010522010
p_heap2 :0x0000000010522080
p_bss   :0x000000000042003c
p_data  :0x0000000000420034
p_const :0x0000000000400980
p_code  :0x00000000004006a0

./x86_64/x86_64_addr
p_stack1:0x00007ffe90775054
p_stack2:0x00007ffe90775058
p_heap1 :0x0000000000702010
p_heap2 :0x0000000000702080
p_bss   :0x0000000000601058
p_data  :0x0000000000601050
p_const :0x0000000000400994
p_code  :0x0000000000400626

./i686/i686_addr
p_stack1:0xbfee6514
p_stack2:0xbfee6518
p_heap1 :0x09cc7008
p_heap2 :0x09cc7070
p_bss   :0x0804a030
p_data  :0x0804a028
p_const :0x08048800
p_code  :0x080484cb

./armv7l/armv7l_addr
p_stack1:0xbecef4bc
p_stack2:0xbecef4b8
p_heap1 :0x00720150
p_heap2 :0x007201b8
p_bss   :0x00021038
p_data  :0x00021030
p_const :0x0001076c
p_code  :0x00010468
p_code2 :0x000106fc

段大小

  • 棧大小
$ ulimit -a |grep stack
stack size              (kbytes, -s) 8192

- [測試棧大小](https://blog.csdn.net/lyh__521/article/details/50115943)
- 棧通常爲4MB // 但ulimit -a |grep stack顯示爲8MB
#include<stdio.h>
#include<stdlib.h>

int   i = 1;  //記錄申請的次數

void func()
{
    char   a[1048576];  //一次申請 1 M 便於計算

    printf("NO.%d  %ld 字節 %p\n",i,sizeof(a),a);

    i++;
    func();
}

main()
{
    func();
}
  • data大小
data seg size           (kbytes, -d) unlimited
  • 堆大小
#include <stdlib.h>
#include <stdio.h>


int main(void)
{
    void* p = malloc(1000000);
    int i=1;

    while(p){
        p = malloc(1000000);
        i++;
        printf("堆容量爲(M): %d\n",i);
    }
    printf("堆容量爲(M): %d\n",i);
    return 0;

}
// 在 arch:i686下,堆容量3205MB
// 在 arch:x86_64 下,堆容量56079GB
堆≈虛擬內存大小-1GB
  • code 段 和 .rodata段
.code 跟你寫的所有函數翻譯彙編成的二進制大小有關係
.ro-data 跟你寫的 const 變量的多少有關係.

內核空間(虛擬內存)

在linux啓動log中查找關鍵字:
Virtual kernel memory layout
  • arm32
[    0.000000] Memory: 1014364K/1032192K available (3956K kernel code, 237K rwdata, 1320K rodata, 231K init, 276K bss, 17828K reserved, 270336K highmem)       
[    0.000000] Virtual kernel memory layout:
[    0.000000]     vector  : 0xffff0000 - 0xffff1000   (   4 kB)
[    0.000000]     fixmap  : 0xfff00000 - 0xfffe0000   ( 896 kB)
[    0.000000]     vmalloc : 0xf0000000 - 0xff000000   ( 240 MB)
[    0.000000]     lowmem  : 0xc0000000 - 0xef800000   ( 760 MB)
[    0.000000]     pkmap   : 0xbfe00000 - 0xc0000000   (   2 MB)
[    0.000000]     modules : 0xbf000000 - 0xbfe00000   (  14 MB)
[    0.000000]       .text : 0xc0008000 - 0xc052f41c   (5278 kB) // 3956K kernel code + 320K rodata
[    0.000000]       .init : 0xc0530000 - 0xc0569d00   ( 232 kB) // 231K init
[    0.000000]       .data : 0xc056a000 - 0xc05a5540   ( 238 kB) // 1320K rodata
[    0.000000]        .bss : 0xc05a554c - 0xc05ea584   ( 277 kB) // 276K bss
  • arm64

  • x86
[    0.000000] Memory: 2008144K/2096628K available (8866K kernel code, 887K rwdata, 3468K rodata, 1092K init, 848K bss, 88484K reserved, 0K cma-reserved, 1187720K highmem)
[    0.000000] virtual kernel memory layout:
                   fixmap  : 0xfff14000 - 0xfffff000   ( 940 kB)
                 cpu_entry : 0xffa00000 - 0xffb39000   (1252 kB)
                   pkmap   : 0xff800000 - 0xffa00000   (2048 kB)
                   vmalloc : 0xf7ffe000 - 0xff7fe000   ( 120 MB)
                   lowmem  : 0xc0000000 - 0xf77fe000   ( 887 MB)
                     .init : 0xdbd03000 - 0xdbe14000   (1092 kB)
                     .data : 0xdb8a8bb4 - 0xdbcefec0   (4380 kB)
                     .text : 0xdb000000 - 0xdb8a8bb4   (8866 kB)
  • x86_64
[    0.000000] Memory: 1956488K/2096628K available (12300K kernel code, 2480K rwdata, 4212K rodata, 2428K init, 2712K bss, 140140K reserved, 0K cma-reserved)

總結

總的來看
linux內核管理的段有 .bss .data .init .text cpu_entry fixmap lowmem modules pkmap vector vmalloc
linux給應用程序的段有 .code .rodata .data .bss .stack .heap

rtos 的段 和 rtos 應用程序的段都是混雜在一起的.(物理地址)
但是linux內核空間所在的段和linux應用程序的段都不在一塊.(虛擬地址)

對於32位linux來講
linux內核空間位置: 0xc000 0000 - 0xffff ffff
linux應用程序位置: 0x0000 0000 - 0xbfff ffff
對於64位linux來講
linux內核空間位置: 0xffff 0000 0000 0000 - 0xffff ffff ffff ffff
linux應用程序位置: 0x0000 0000 0000 0000 - 0x0000 7fff ffff ffff
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章