内核中的内存与分配

1. 内核空间和用户空间 1G ~ 3G 用户空间使用的地址范围(3G)
                      3G ~ 4G 内核空间使用的地址范围(1G)
2. 内存的申请
(1)用户空间的内存申请: malloc free
(2)内核空间的内存申请:
a. __get_free_pages() 与void free_page(unsigned long addr)
extern unsigned long __get_free_pages(gfp_t gfp_mask, unsigned int order); 
gfp_mask : 内存申请的标识
#define GFP_NOWAIT (GFP_ATOMIC & ~__GFP_HIGH)
#define GFP_ATOMIC (__GFP_HIGH)
#define GFP_NOIO (__GFP_WAIT)
#define GFP_NOFS (__GFP_WAIT | __GFP_IO)
#define GFP_KERNEL (__GFP_WAIT | __GFP_IO | __GFP_FS)
GFP_KERNEL(带睡眠的) :含义是在内核空间申请内存,如果内存不足时,进程会睡眠等待,因此不能在自旋锁和中断上下文中使用   
GFP_ATOMIC (不带睡眠的):含义是在内核空间申请内存,如果内存不足时,则不等待立即返回
order :表示的是多少页 ,order允许的最大值是10(即1024页)或者 11(即2048页),
依赖于具体的硬件平台
      调用者指定所需整页的阶数作为参数之一来请求(按照页进行分配)
      所申请的页将会被加入内核空间
      所分配的物理RAM空间是连续的

b . kmalloc 和 kfree  
内存的申请: static __always_inline void * kmalloc(size_t size, gfp_t flags)
size : 当kmalloc申请内存空间时,内核就会将一个刚好足够大的空闲内存块分配出来。
比如要申请100字节,kmalloc就会返回一个128字节的内存块
在4k字节大小页面的系统上,分配的最小内存块是32字节,最大128k字节
内存的释放: void kfree(const void *objp)
objp : @objp: pointer returned by kmalloc.

c . vmalloc 和vfree 
内存的申请: void * vmalloc(unsigned long size)
size: 申请内存的大小
内存的释放: void vfree(const void *addr)
addr : memory base address

d. 内核启动前,手动预留一块大内存 
e. 内存池 slab


3. IO端口与IO内存
   IO端口: 一般用在X86系统上,有专用的指令访问IO端口的设备,
   IO内存: 一般在ARM,PowerPC,MIPS,外设会占用一个总线地址,这个地址就是IO内存地址 

4. IO内存映射函数 ioremap函数
ioremap映射函数与取消映射函数 iounmap 
a.依赖头文件: <asm/io.h> 
b. 把一个物理地址映射成一个虚拟地址,在内核中可以访问这个虚拟地址
static inline void __iomem *ioremap(phys_addr_t offset, unsigned long size)
{
     return (void __iomem*) (unsigned long)offset;
}
offset : 物理地址的开始
size : 需要转换的大小
返回值: void __iomem *
c . 取消映射
void iounmap(volatile void __iomem *addr) 
addr :要取消映射的开始地址

5. IO内存地址的访问
   读一个字节:
   unsigned int ioread8(void *addr);
   unsigned int readb(void *addr)(早期内核版本,以后可以被淘汰用法)
   读2个字节
   unsigned int ioread16(void *addr);
   unsigned int readw(void *addr)
   读4个字节
   unsigned int ioread32(void *addr);
   unsigned int readl(void *addr)

   写一个字节:
   void iowrite8(u8 value, void *addr);
   void writeb(u8 value, void *addr);
   写2个字节:
   void iowrite16(u16 value, void *addr);
   void writew(u16 value, void *addr);
   写4个字节
   void iowrite32(u32 value, void *addr);
   void writel(u32 value, void *addr);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值