linux内核内存管理相关问题

内核编译和嵌入式产品的设计与开发
回复
我是swk
帖子: 7
注册时间: 2021-12-04 18:11
系统: windows+linux

linux内核内存管理相关问题

#1

帖子 我是swk » 2021-12-04 19:32

《深入理解linux内核 第三版》第二章有这么一张图描述linux内核代码段数据段在内存中的占用情况:
Screenshot_2021-12-04_18-21-16.png
同样是这本书 第八章、内存管理 中讲到linux把内存分为三个区:
Screenshot_2021-12-04_18-23-58.png
我想问的是,这16M不是包括内核代码吗,用于DMA不是矛盾吗?
头像
astolia
论坛版主
帖子: 6450
注册时间: 2008-09-18 13:11

Re: linux内核内存管理相关问题

#2

帖子 astolia » 2021-12-07 22:21

并不矛盾,是你理解岔了。ISA总线的DMA处理器只能访问地址低于16MB的内存,这个16MB限制是由ISA总线地址位数带来的,只是表示它能寻址的范围,并不是说它每次都会一次性读写16MB的数据,所以并不需要将整个ZONE_DMA中的全部内存都留给它使用,kernel可以占用其中的一部分。
我是swk
帖子: 7
注册时间: 2021-12-04 18:11
系统: windows+linux

Re: linux内核内存管理相关问题

#3

帖子 我是swk » 2021-12-08 23:57

astolia 写了: 2021-12-07 22:21 并不矛盾,是你理解岔了。ISA总线的DMA处理器只能访问地址低于16MB的内存,这个16MB限制是由ISA总线地址位数带来的,只是表示它能寻址的范围,并不是说它每次都会一次性读写16MB的数据,所以并不需要将整个ZONE_DMA中的全部内存都留给它使用,kernel可以占用其中的一部分。
谢谢!这几天查了很多资料,有一篇文章里的图挺形象的:
20170327204706119.jpg
20170327204805121.jpg
也就是说内核代码不会占用ZONE_DMA,是ZONE_NORMAL开始存放内核代码的?
那么我第一帖里那个内存分布图有没有可能举例的是arm平台的?因为我看到arm linux的资料举例都是加载0x100这个地址,跟图里的吻合:
20181226214246667.JPG
文章地址:
https://blog.csdn.net/farmwang/article/details/66976818
https://blog.csdn.net/whahu1989/article ... s/85255538
头像
astolia
论坛版主
帖子: 6450
注册时间: 2008-09-18 13:11

Re: linux内核内存管理相关问题

#4

帖子 astolia » 2021-12-09 23:52

我是swk 写了: 2021-12-08 23:57 谢谢!这几天查了很多资料,有一篇文章里的图挺形象的:

也就是说内核代码不会占用ZONE_DMA,是ZONE_NORMAL开始存放内核代码的?
别忘了,内核的加载地址,是在编译内核时由编译者决定的,0x00100000(1MB)只是32位x86架构上的早期版本内核中定义的一个默认值而已。你完全可以在编译时通过设定CONFIG_PHYSICAL_START的值将其放到ZONE_NORMAL甚至是ZONE_HIMEM里。所以真没必要太过计较它具体的值是多少。

我去查了一下,内核是从2009年发布的2.6.31版开始,把x86平台上的加载地址的默认值由原来的0x00100000改成了0x01000000,一直沿用到现在。图上说的就是这种加载地址为0x01000000(16MB)的情况。
我是swk 写了: 2021-12-08 23:57 那么我第一帖里那个内存分布图有没有可能举例的是arm平台的?因为我看到arm linux的资料举例都是加载0x100这个地址,跟图里的吻合:
要注意一点,讨论内存地址的时候,一般都是以字节为计数单位。而你一楼的图里面,是以页框page frame为单位的。一个page frame是4k=4096字节,0x100*4096=0x00100000,还是那个默认加载地址
我是swk
帖子: 7
注册时间: 2021-12-04 18:11
系统: windows+linux

Re: linux内核内存管理相关问题

#5

帖子 我是swk » 2021-12-10 9:22

astolia 写了: 2021-12-09 23:52
我是swk 写了: 2021-12-08 23:57 谢谢!这几天查了很多资料,有一篇文章里的图挺形象的:

也就是说内核代码不会占用ZONE_DMA,是ZONE_NORMAL开始存放内核代码的?
别忘了,内核的加载地址,是在编译内核时由编译者决定的,0x00100000(1MB)只是32位x86架构上的早期版本内核中定义的一个默认值而已。你完全可以在编译时通过设定CONFIG_PHYSICAL_START的值将其放到ZONE_NORMAL甚至是ZONE_HIMEM里。所以真没必要太过计较它具体的值是多少。

我去查了一下,内核是从2009年发布的2.6.31版开始,把x86平台上的加载地址的默认值由原来的0x00100000改成了0x01000000,一直沿用到现在。图上说的就是这种加载地址为0x01000000(16MB)的情况。
我是swk 写了: 2021-12-08 23:57 那么我第一帖里那个内存分布图有没有可能举例的是arm平台的?因为我看到arm linux的资料举例都是加载0x100这个地址,跟图里的吻合:
要注意一点,讨论内存地址的时候,一般都是以字节为计数单位。而你一楼的图里面,是以页框page frame为单位的。一个page frame是4k=4096字节,0x100*4096=0x00100000,还是那个默认加载地址
谢谢大佬!大佬好强!高手果然都在论坛里! :Cool
回复