x86架构学习内存管理的单元
在基于操作系统编写程序的时候基本不需要管理程序的运行地址,而且同一个程序,在系统中运行几个实例的时候,这几个实例的内存都是一样的,这是因为他们都运行在虚拟内存上,x86虚拟内存管理比较简单,这里从分页到寄存器到内存的具体管理方式逐步了解。
虚拟内存的基本管理单元都是以页为单位,一般1页4KB字节,在虚拟内存上的地址叫做虚拟地址,虚拟地址到实际的物理地址经过了几次转换,一般书中把虚拟地址叫做逻辑地址,在未打开分页机制之前逻辑地址等于物理地址,打开分页机制之后逻辑地址(虚拟地址)到物理地址的转换如图所示:
逻辑地址到物理地址的转换使用的是页映射,以页为基本单位。在打开保护模式后逻辑地址到线性地址的转换与描述符里面的基地址和指定的IP地址有关:
线性地址 = 描述符里的基地址+指定的IP地址
线性地址到物理地址的转换关系如图所示:
PDE:页目录条目 PTE:页表条目
这里我们忽略地址扩展,认为只有32位地址线,所以可以访问4GB的空间,页目录条目存放的是PTE页表条目的地址,页表条目存放的是页地址的(4KB)首地址。
PDE条目可以有1024个,每个PTE可以有1024页首地址,每页4kb总的可以表示的内存大小为:
4GB = 1024*1024*4096
PDE存放在CR3寄存器,关于CRx寄存器简单描述:
控制寄存器(CR0、CR 1、CR2和CR3)用於控制和确定处理器的操作模式以及当前执行任务的特性。
- CR0:中含有控制处理器操作模式和状态的系统控制标志;
- CR1:保留不用;
- CR2:含有导致页错误的线性位址。
- CR3:中含有页目錄表实体记忆体基底位址,因此该寄存器也被称为页目录基底位址寄存器PDBR(Page-Directory Base address Register) 。
其中CR0寄存器在开启保护模式时使用过(PE位),开启页的转换也要使用CR0(PG位).
CR0寄存器
进行转换时,先是从由寄存器cr3指定的页目录中根据线性地址的高10位得到页表地址,然后在页表中根据线性地址的第12到21位得到物理页首地址,将这个首地址加上线性地址低12位便得到了物理地址。
分页机制是否生效的开关位于cr0的最高位PG位,如果PG=1,则分页机制生效。当准备好了页目录表和页表,并将cr3指向页目录表之后,只需要置PG位,分页机制就开始工作了。
PDE格式如图:
PTE格式如图:
PDE和PTE中各位的解释:
- P存在位,表示当前条目所指向的页或页表是否在物理内存中。P=0表示页不在内存中,如果处理器试图访问此页,将会产生页异常(page-fault exception,#PF);P=1表示页在内存中
- R/W指定一个页或者一组页(比如,此条目是指向页表的页目录条目)的读写权限。此位与U/S位和寄存器cr0中的WP位相互作用。R/W=0表示只读;R/W=1表示可读并可写。
- U/S指定一个页或者一组页(比如,此条目是指向页表的页目录条目)的特权级。此位与R/W位和寄存器cr0中的WP位相互作用。U/S=0表示系统级别(Supervisor Privilege Level),如果CPL为0、1或2,那么它便是在此级别;U/S=1表示用户级别(User Privilege Level),如果CPL为3,那么它便是在此级别。如果cr0中的WP位为0,那么即便用户级(User P.L.)页面的R/W=0,系统级(Supervisor P.L.)程序仍然具备写权限;如果WP位为1,那么系统级(Supervisor P.L.)程序也不能写入用户级(User P.L.)只读页。
- PWT用于控制对单个页或者页表的缓冲策略。PWT=0时使用Write-back缓冲策略;PWT=1时使用Write-through 缓冲策略,当cr0寄存器的CD(Cache-Disable)位被设置时会被忽略。
- PCD用于控制对单个页或者页表的缓冲。PCD=0时页或页表可以被缓冲;PCD=1时页或页表不可以被缓冲。当cr0寄存器的CD(Cache-Disable)位被设置时会被忽略。
- A指示页或页表是否被访问。此位往往在页或页表刚刚被加载到物理内存中时被内存管理程序清零,处理器会在第一次访问此页或页面时设置此位。而且,处理器并不会自动清除此位,只有软件能清除它。
- D指示页或页表是否被写入。此位往往在页或页表刚刚被加载到物理内存中时被内存管理程序清零,处理器会在第一次写入此页或页面时设置此位。而且,处理器并不会自动清除此位,只有软件能清除它。A位和D位都是被内存管理程序用来管理页和页表从物理内存中换入和换出的。
- PS决定页大小。PS=0时页大小为4KB,PDE指向页表。
- PAT选择PAT(Page Attribute Table)条目。Pentium III以后的CPU开始支持此位,在此不予讨论,并在我们的程序中设为0。
- G指示全局页。如果此位被设置,同时cr4中的PGE位被置,那么此页的页表或页目录条目不会在TLB中变得无效,即便cr3被加载或者任务切换时也是如此。
处理器会将最近常用的页目录和页表项保存在一个叫做TLB(Translation Lookaside Buffer)的缓冲区中。只有在TLB中找不到被请求页的转换信息时,才会到内存中去寻找。这样就大大加快了访问页目录和页表的时间。在重新设置 CR3寄存器 时会刷新TLB(页表条目设置了G标志位就,会一直存在到TLB中)。
代码示例:
;----------------------------------------------------------------------------
; 描述符类型值说明
; 其中:
; DA_ : Descriptor Attribute
; D : 数据段
; C : 代码段
; S : 系统段
; R : 只读
; RW : 读写
; A : 已访问
; 其它 : 可按照字面意思理解
;----------------------------------------------------------------------------
DG_4KB EQU 0x8000 ;limit * 4KB
DG_BYTE EQU 0x0000 ;limit * 1byteDA_32 EQU 4000h ; 32 位段DA_DPL0 EQU 00h ; DPL = 0
DA_DPL1 EQU 20h ; DPL = 1
DA_DPL2 EQU 40h ; DPL = 2
DA_DPL3 EQU 60h ; DPL = 3
;----------------------------------------------------------------------------
; 存储段描述符类型值说明
;----------------------------------------------------------------------------
DA_DR EQU 90h ; 存在的只读数据段类型值
DA_DRW EQU 92h ; 存在的可读写数据段属性值
DA_DRWA EQU 93h ; 存在的已访问可读写数据段类型值
DA_C EQU 98h ; 存在的只执行代码段属性值
DA_CR EQU 9Ah ; 存在的可执行可读代码段属性值
DA_CCO EQU 9Ch ; 存在的只执行一致代码段属性值
DA_CCOR EQU 9Eh ; 存在的可执行可读一致代码段属性值
;----------------------------------------------------------------------------
; 系统段描述符类型值说明
;----------------------------------------------------------------------------
DA_LDT EQU 82h ; 局部描述符表段类型值
DA_TaskGate EQU 85h ; 任务门类型值
DA_386TSS EQU 89h ; 可用 386 任务状态段类型值
DA_386CGate EQU 8Ch ; 386 调用门类型值
DA_386IGate EQU 8Eh ; 386 中断门类型值
DA_386TGate EQU 8Fh ; 386 陷阱门类型值
;----------------------------------------------------------------------------;----------------------------------------------------------------------------
; 选择子类型值说明
; 其中:
; SA_ : Selector AttributeSA_RPL0 EQU 0 ; ┓
SA_RPL1 EQU 1 ; ┣ RPL
SA_RPL2 EQU 2 ; ┃
SA_RPL3 EQU 3 ; ┛SA_TIG EQU 0 ; ┓TI
SA_TIL EQU 4 ; ┛
;----------------------------------------------------------------------------
;----------------------------------------------------------------------------
;虚拟内存设置
;0-P 存在位,
;1-RW 读写位,
;2-U/S超级权限位
;3-PWT 写穿或者写回
;4-PCD cache 使能位
;5-accessed 是否访问了
;6-D 本页修改标志
;7-PAT 页表属性索引
;8-G 全局页代码TLB持续锁存不会因为写CR3而存储
;9-11 AVail保留系统程序员可以使用
;----------------------------------------------------------------------------
DT_P equ 0x01
DT_RW equ 0x02
DT_US equ 0x04
DT_PWT equ 0x08
DT_PCD equ 0x10
DT_A equ 0x20
DT_D equ 0x40
DT_PS equ 0x80
DT_PAT equ 0x80
DT_G equ 0x100
; 宏 ------------------------------------------------------------------------------------------------------
;
; 描述符
; usage: Descriptor Base, Limit, Attr
; Base: dd
; Limit: dd (low 20 bits available)
; Attr: dw (lower 4 bits of higher byte are always 0)
%macro Descriptor 3dw %2 & 0FFFFh ; 段界限 1 (2 字节)dw %1 & 0FFFFh ; 段基址 1 (2 字节)db (%1 >> 16) & 0FFh ; 段基址 2 (1 字节)dw ((%2 >> 8) & 0F00h) | (%3 & 0F0FFh) ; 属性 1 + 段界限 2 + 属性 2 (2 字节)db (%1 >> 24) & 0FFh ; 段基址 3 (1 字节)
%endmacro ; 共 8 字节
;
; 门
; usage: Gate Selector, Offset, DCount, Attr
; Selector: dw
; Offset: dd
; DCount: db
; Attr: db
%macro Gate 4dw (%2 & 0FFFFh) ; 偏移 1 (2 字节)dw %1 ; 选择子 (2 字节)dw (%3 & 1Fh) | ((%4 << 8) & 0FF00h) ; 属性 (2 字节)dw ((%2 >> 16) & 0FFFFh) ; 偏移 2 (2 字节)
%endmacro ; 共 8 字节
; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^所有 equ 定义地方^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
;描述符里面的限制
text1_limit equ text1_end - text1_start - 1
text2_limit equ text2_end - text2_start - 1
text3_limit equ text3_end - text3_start - 1
text4_limit equ text4_end - text4_start - 1
text5_limit equ text5_end - text5_start - 1gdt_limit equ gdtr_desc_end - gdtr_desc_start - 1
idt_limit equ idtr_desc_end - idtr_desc_start - 1sp0_limit equ data2_sp0_end - data2_sp0_start - 1
sp3_limit equ data3_sp3_end - data3_sp3_start - 1
data4sp0_limit equ data4_sp0_end - data4_sp0_start - 1tss_limit equ tss_end - tss_start - 1
;选择描述符
select_text2 equ text2_descrip - gdtr_desc_start
select_text3 equ (text3_descrip - gdtr_desc_start)|SA_RPL3
select_text4 equ (text4_descrip - gdtr_desc_start);|SA_RPL3
select_text5 equ text5_descrip - gdtr_desc_startselect_data1 equ data1_descrip - gdtr_desc_start
select_sp0 equ data2_sp0_descrip - gdtr_desc_start
select_sp3 equ (data3_sp3_descrip - gdtr_desc_start)|SA_RPL3
select_data4sp0 equ (data4_sp0_descrip - gdtr_desc_start)
select_tss equ tss_descrip - gdtr_desc_start
select_gate1 equ (gate1_descrip - gdtr_desc_start)|SA_RPL3PAGE_D_DESCRIP equ ((DT_P|DT_RW|DT_US)+4096)
PAGE_T_DESCRIP equ ((DT_P|DT_RW|DT_US)+0);内存地址定义
ADDR_4MSize equ 1024*1024*4
ADDR_1MSize equ 1024*1024*1;代码说明:
;从实模式代码段1跳转到代码段2保护模式,再跳转到低特权级,测试调用门,再测试返回;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^代码段^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^jmp text1_start ;这是从boot跳转到此处 ds=0x1000 cs=0x1000
;~~~~~~~~~~~~~~~~text1~~~~~~~~~~~~~~~~
section text1 align=32bits 16
text1_start:mov eax,0x01
init_protect:;设置 gdt表;代码段 2mov ax,text2_startmov [text2_descrip+2],ax;堆栈 0 levelmov ax,data2_sp0_startmov [data2_sp0_descrip+2],ax;堆栈 3 levelmov ax,data3_sp3_startmov [data3_sp3_descrip+2],ax;代码段 3mov ax,text3_startmov [text3_descrip+2],ax ;代码段 4mov ax,text4_startmov [text4_descrip+2],ax ;代码段 5mov ax,text5_startmov [text5_descrip+2],ax;tssmov ax,tss_startmov [tss_descrip+2],ax ;堆栈 4,0 level mov ax,data4_sp0_startmov [data4_sp0_descrip+2],ax;init gdt
init_gdt:;text2 descripmov ax,gdt_limitmov [gdtr_48_start],axmov ax,gdtr_desc_startmov [gdtr_48_start+2],axlgdt [gdtr_48_start];打开A20地址in al,0x92or al,0x02out 0x92,al;打开保护模式climov eax,cr0or eax,0x01mov cr0,eaxjmp select_text2:0
text1_end:;~~~~~~~~~~~~~~~~text2~~~~~~~~~~~~~~~~
section text2 align=32bits 32
text2_start:mov eax,0x02mov ax,select_data1mov es,axmov ebp,ADDR_1MSizemov dword [es:ebp],0x12345678 ;测试读写4M字节处检验地址访问;init idt
init_idt:mov ax,idt_limitmov [idtr_48_start],axmov ax,idtr_desc_startmov [idtr_48_start+2],axlidt [idtr_48_start];为下一个任务调用调用门做准备mov ax,select_tssltr ax ;初始化0特权级堆栈mov ax,select_sp0mov ss,axmov eax,sp0_limitmov esp,eax
init_8259A: mov al, 011hout 020h, al ; 主8259, ICW1.call io_delayout 0A0h, al ; 从8259, ICW1.call io_delaymov al, 020h ; IRQ0 对应中断向量 0x20out 021h, al ; 主8259, ICW2.call io_delaymov al, 028h ; IRQ8 对应中断向量 0x28out 0A1h, al ; 从8259, ICW2.call io_delaymov al, 004h ; IR2 对应从8259out 021h, al ; 主8259, ICW3.call io_delaymov al, 002h ; 对应主8259的 IR2out 0A1h, al ; 从8259, ICW3.call io_delaymov al, 001hout 021h, al ; 主8259, ICW4.call io_delayout 0A1h, al ; 从8259, ICW4.call io_delaymov al, 11111111b ; 仅仅开启定时器中断;mov al, 11111111b ; 屏蔽主8259所有中断out 021h, al ; 主8259, OCW1.call io_delaymov al, 11111111b ; 屏蔽从8259所有中断out 0A1h, al ; 从8259, OCW1.call io_delaysti;跳转到特权级3代码段push select_sp3push sp3_limitpush select_text3push 0 ;因为描述符里面的基地址就是text3的开始地址所以我们就直接压栈地址0即可retfio_delay:nopnopnopnoprettext2_end:;~~~~~~~~~~~~~~~~text3~~~~~~~~~~~~~~~~
section text3 align=32bits 32
text3_start:mov eax,0x03mov ebx,0x04mov ecx,0x05mov edx,0x06push eaxpush ebxpush ecxpush edxcall select_gate1:0mov ax,select_data1mov es,axmov ebp,ADDR_1MSize*5mov eax,[es:ebp]mov eax,0x87654321mov [es:ebp],eaxmov eax,data2_sp0_startmov ebx,data3_sp3_startmov ecx,data4_sp0_startmov edx,gdtr_desc_startint 0x80 jmp $
text3_end:
;~~~~~~~~~~~~~~~~text4~~~~~~~~~~~~~~~~
section text4 align=32bits 32
text4_start:mov eax,0x04;init virt memory;0-4095mov ax,select_data1mov es,ax;初始化页目录mov edi,0x00mov eax,PAGE_D_DESCRIPmov ecx,1024
loop_virtureD_init:stosd add eax,4096loop loop_virtureD_init;初始化页0-4M物理地址mov edi,4096mov ecx,1024mov eax,PAGE_T_DESCRIP
loop_virtureP_init:stosd add eax,4096loop loop_virtureP_init ;初始化页把4-8M虚拟地址也映射到0-4M物理地址mov edi,8192mov ecx,1024mov eax,PAGE_T_DESCRIP
loop_virtureP1_init:stosd add eax,4096loop loop_virtureP1_init mov eax,0x00;mov cr3,eaxmov eax,cr0or eax,0x8000_0000mov cr0,eaxretf 16 jmp $
text4_end: ;~~~~~~~~~~~~~~~~text4~~~~~~~~~~~~~~~~
section text5 align=32bits 32
text5_start:mov eax,eaxmov ebx,ebxmov ecx,ecxmov edx,edx;pop eax ;有错误码需要弹出错误码iretdtext5_end: ;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^idt描述符段^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
;idt descrip
section idtr_desc align=32
idtr_desc_start:
%rep 256Gate select_text5,0,0,(DA_386IGate|DA_DPL3) ;宏定义最好加上括号
%endrep
; times 256*2 -2 dd 0x0000_0000
idtr_desc_end:;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^gdt代码段^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
;gdt descrip
section gdtr_desc align=32
gdtr_desc_start:
null1_descrip: Descriptor 0,0,0
text2_descrip: Descriptor 0x10000,text2_limit,(DA_CR|DA_32) ;text2代码段 宏定义最好加上括号
data1_descrip: Descriptor 0x00000,0x8000-1,(DA_DRW|DA_32|DA_DPL3|DG_4KB) ;32M字节描述所有数据宏定义最好加上括号
data2_sp0_descrip: Descriptor 0x10000,sp0_limit,(DA_DRW|DA_32)
data3_sp3_descrip: Descriptor 0x10000,sp3_limit,(DA_DRW|DA_32|DA_DPL3)
text3_descrip: Descriptor 0x10000,text3_limit,(DA_CR|DA_32|DA_DPL3) ;text3代码段宏定义最好加上括号
tss_descrip: Descriptor 0x10000,tss_limit,(DA_386TSS)
text4_descrip: Descriptor 0x10000,text4_limit,(DA_CR|DA_32);|DA_DPL3 ;text4代码段宏定义最好加上括号
data4_sp0_descrip: Descriptor 0x10000,data4sp0_limit,(DA_DRW|DA_32)
gate1_descrip: Gate select_text4,0,4,(DA_386CGate|DA_DPL3)
text5_descrip: Descriptor 0x10000,text5_limit,(DA_CR|DA_32) ;text5代码段宏定义最好加上括号gdtr_desc_end:
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^tss 数据段^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
section tss align=32
tss_start:dd 0x00 ;0dd data4sp0_limit;esp0dd select_data4sp0;ss0dd 0x00;esp1dd 0x00;ss1dd 0x00;esp2dd 0x00;ss2dd 0x00 ;gr3 pdbrdd 0x00 ;eipdd 0x00 ;eflagdd 0x00;eaxdd 0x00;ecxdd 0x00;edxdd 0x00;ebxdd 0x00;espdd 0x00;ebpdd 0x00;esidd 0x00;edidd 0x00;esdd 0x00;csdd 0x00;ssdd 0x00;dsdd 0x00;fsdd 0x00;gsdd 0x00;LDT selectdw 0x00;调试陷阱标志dw $-tss_start+2;设置IO访问使能的位的偏移地址db 0xff;结尾标志
tss_end:
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^数据段^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
section data2_sp0 align=32;数据段初始化用来做堆栈 0特权级
data2_sp0_start:data2_start equ (data2_sp0_start+0x10000)times 1024 db 0x00
data2_sp0_end:section data3_sp3 align=32;数据段初始化用来做堆栈 3特权级
data3_sp3_start:data3_start equ (data3_sp3_start+0x10000)times 1024 db 0x00
data3_sp3_end:section data4_sp0 align=32;数据段初始化用来做堆栈 3特权级
data4_sp0_start:times 1024 db 0x00
data4_sp0_end:
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^gdtr idtr指针设置处^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
;设置idtr
section idtr_addr align=32
idtr_48_start:dw 0x0000dd 0x0001_0000
idtr_48_end:;设置gdtr
section gdtr_addr align=32
gdtr_48_start:dw 0x0000dd 0x0001_0000
gdtr_48_end:
代码说明:本代码加载地址在 0x10000处开始执行,进入保护模式后,在调用门中设置页表和页目录,从内存0地址开始设置页目录,页表,从代码中可以知道,0x0000-0x1000KB(4KB)设置的页目录,0x1000-0x2000(8KB)设置的第一个页表映射到0-4M(一个页表1024个条目,每个条目的高20位是4KB地址的首地址,也就是包含4KB字节,一页映射4M字节内存),0x2000-0x3000(12KB)设置的第二个页表,这里的第二个页表也映射到0-4M字节,这里我们访问1M地址内存先写0x12345678 ,地址做完地址映射之后再去检查该地址检查值是否正确,然后再往5M地址处写0x87654321,再查1M该地址处值是否是0x87654321,如果是该值说明映射成功。
可以看出线性地址是5M处的内容是刚开始没有映射的地址内存时写的0x12345678
往5M字节线性地址内存处写0x87654321,检查1M地址内存处是0x87654321,地址映射成功。
这里检查物理地址5M处值是 0x0000_0000 确认没有错误。
注意:bochs的 xp 是查看物理地址命令,x命令是查看线性地址命令
页目录U/S标志位测试:
修改红框中代码,改为和图中一致
测试结果:
代码在返回了用户模式时进入了中断,是因为我们把代码地址的页表设置为系统模式,只有CPL为0,1,2的代码才能访问该地址,这里出现了访问异常并且把异常地址设置到CR2寄存器处。在操作系统中可以凭借这个保护防止地址溢出之类的问题和进行页表相关管理处理。可以在异常中断处理之后重新返回该地址处运行。
参考资料:
Intel 80386 程序员参考手册 · 看云
《x86汇编语言-从实模式到保护模式》 作者:李忠
《自己动手写操作系统》 作者:于渊
《Orange‘s一个操作系统的实现》 作者:于渊
《汇编语言》 作者:王爽
x86架构学习内存管理的单元相关推荐
- Linux内核学习--内存管理模块
Linux内核学习--内存管理模块 首先,Linux内核主要由五个部分组成,他们分别是:进程调度模块.内存管理模块.文件系统模块.进程间通信模块和网络接口模块. 本部分所讲的内存是内存管理模块,其主要 ...
- UNIX再学习 -- 内存管理
C 语言部分,就一再的讲内存管理,参看:C语言再学习 -- 再论内存管理 UNIX.Linux 部分还是要讲,足见其重要. 一.存储空间布局 1.我们先了解一个命令 size,继而引出我们今天要讲的 ...
- 【Linux 内核】Linux 内核体系架构 ( 进程调度 | 内存管理 | 中断管理 | 设备管理 | 文件系统 )
文章目录 一.进程调度 二.内存管理 三.中断管理 四.设备管理 五.文件系统 一.进程调度 进程调度 : 进程 是 系统中 进行 资源分配 的 基本单位 ; 每个进程 在 运行时 , 都 感觉自己占 ...
- x86架构学习笔记实模式
8086是Inter公司的第一款16微处理器,诞生于1978年,8086在市场上获得了巨大成功,所以后期芯片都兼容它. 8086有8个16位通用寄存器 AX,BX,CX,DX,SI,DI,BP,SP其 ...
- C语言再学习 -- 内存管理
参看:malloc()和free() 参看:百度百科 -- malloc函数 malloc ( )函数: malloc ( ) 向系统申请分配指定size个字节的内存空间.返回类型是 void* 类型 ...
- 【软件开发底层知识修炼】三 深入浅出处理器之三 内存管理与内存管理单元(MMU)
学习交流加 个人qq: 1126137994 个人微信: liu1126137994 学习交流资源分享qq群: 962535112 上一篇文章学习了中断的概念与意义,以及中断的应用-断点调试原理.点击 ...
- 内存管理基础学习笔记 - 3.1 进程地址空间 - VMA线性区
目录 1. 前言 2. 进程地址空间 3. 用户空间与内核空间的隔离 4. 进程地址空间主要数据结构 struct mm_struct struct vm_area_struct 5. vma的标志属 ...
- linux按进程分配物理内存,linux下内存管理学习心得(一)
最近在学习内存管理的时候,发现对linux下的所谓内存如何管理如何分配都不熟悉,通过最近的查阅资料可总结如下,如有不妥之处欢迎大家批评与指正. 总的的来说linux的内存管理其实主要难理解的是以下几个 ...
- Linux内核内存管理架构
内存管理子系统可能是linux内核中最为复杂的一个子系统,其支持的功能需求众多,如页面映射.页面分配.页面回收.页面交换.冷热页面.紧急页面.页面碎片管理.页面缓存.页面统计等,而且对性能也有很高的要 ...
最新文章
- 【重磅】吴恩达又一项目Landing.ai曝光,这一次,他是要给传统制造业狠狠开刀!
- 暗通道优先的图像去雾算法(上)
- linux 发送外部邮件
- magento网站建设_外贸网站建设指南,告诉你建站系统怎么选择
- js 正则表达式实现文本验证
- 三星识别文字_比亚迪电子助力三星Galaxy Note 10系列霸气首发!
- 如何限制创建子网站时只能使用指定的模板
- Serv-U和win2003防火墙的设置
- Linux如何实现自动文件同步?
- 计算机网络实验——华为ensp安装和初步使用教程
- apple tv 开发_如何在Apple TV上禁用Siri和定位服务
- js pug 代码_PUG 系列 | 第二课 JS 代码混合、包含引入
- Windows引导修复
- 基于云开发的微信小程序:个人相册ByUestcXiye
- Wifi模块—源码分析Wifi启动(Android P)
- 【C语言】共用体的定义与使用
- 优秀的免费高清图片素材网站推荐
- Faiss相似性搜索类库
- http的长连接和短连接(史上最通俗!)
- 论文详读:Beyond Brightening Low-light Images (Kind++)
热门文章
- 显示手机键盘的回车换行
- 2000+万智能终端、8000+万亿条数据集,长虹如何做快速交互式分析?
- M1芯片的Mac安装Centos !
- Vue 安装echarts-gl引入vue报错
- 工作十年,你的职场核心竞争力在哪里
- 基于Java毕业设计学校图书馆管理系统源码+系统+mysql+lw文档+部署软件
- 一流的产品,繁荣的生态,优质的服务,领先的市场,强大的组织 —2022新年寄语
- Normalized and Geometry-Aware Self-Attention Network for Image Captioning阅读笔记
- 原华为区块链科学家黄连金先生受邀担任Hashgard基金会战略顾问
- HoloView 在 jyputer lab/notebook 不显示总结