linux-0.11分析:init文件 main.c的第一个初始化函数mem_int 第四篇随笔
init文件夹 mian.c
参考 [github这个博主的 厉害][ https://github.com/sunym1993/flash-linux0.11-talk ]
首先先看看这个
mian.c中的主要几行代码吧void main(void)
{
ROOT_DEV = ORIG_ROOT_DEV;
drive_info = DRIVE_INFO; memory_end = (1<<20) + (EXT_MEM_K<<10);
memory_end &= 0xfffff000;
if (memory_end > 16*1024*1024)
memory_end = 16*1024*1024;
if (memory_end > 12*1024*1024)
buffer_memory_end = 4*1024*1024;
else if (memory_end > 6*1024*1024)
buffer_memory_end = 2*1024*1024;
else
buffer_memory_end = 1*1024*1024;
main_memory_start = buffer_memory_end;
#ifdef RAMDISK
main_memory_start += rd_init(main_memory_start, RAMDISK*1024);
#endif mem_init(main_memory_start,memory_end);
trap_init();
blk_dev_init();
chr_dev_init();
tty_init();
time_init();
sched_init();
buffer_init(buffer_memory_end);
hd_init();
floppy_init();
sti();
move_to_user_mode();
if (!fork()) { /* we count on this going ok */
init();
}
/*
注意!!对于任何其他任务,“pause()”意味着我们必须获得一个
*发出唤醒信号,但task0是唯一的例外(请参阅“schedule()”)
*因为任务0在每个空闲时刻被激活(当没有其他任务时
*可以运行)。对于task0,“pause()”只意味着我们去检查其他
*任务可以运行,否则我们返回这里
*/
for(;;) pause();
}
首先看看前两行代码:
ROOT_DEV = ORIG_ROOT_DEV; 这是在设置系统根文件的设备号
drive_info = DRIVE_INFO; 这里是在设置之前存在0x90000位置处的设备信息
再看看这些设备信息吧
| 地址 | 字节 | 存储的东西 |
|---|---|---|
| 0x90000 | 1 | 光标列号 |
| 0x90001 | 1 | 光标行号 |
| 0x90002 | 2 | 内存大小 |
| 0x90004 | 2 | 显示页面 |
| 0x90006 | 1 | 模式模式 |
| 0x90007 | 1 | 窗口宽度 |
| 0x90008 | 2 | 配置参数 |
| 0x9000A | 2 | 配置参数 |
| 0x9000C | 2 | 配置参数 |
| 0x90080 | 16 | hd0硬盘信息 |
| 0x90010 | 16 | hd1硬盘信息 |
接下来看看中间那段代码
memory_end = (1<<20) + (EXT_MEM_K<<10);
memory_end &= 0xfffff000;
if (memory_end > 16*1024*1024) //内存是否大于16MB
memory_end = 16*1024*1024; //如果大于,就memory_end把置为16MB
if (memory_end > 12*1024*1024) //内存是否大于12MB
buffer_memory_end = 4*1024*1024;//如果大于,就把buffer_memory_end置为4MB
else if (memory_end > 6*1024*1024) //内存是否大于6MB
buffer_memory_end = 2*1024*1024;//如果大于,就buffer_memory_end把置为2MB
else
buffer_memory_end = 1*1024*1024;//如果都不满足,就buffer_memory_end把置为2MB main_memory_start = buffer_memory_end;//把buffer_memory_end值给main_memory_start
#ifdef RAMDISK
main_memory_start += rd_init(main_memory_start, RAMDISK*1024);
//main_memory_start加上一段距离
#endif
仔细看会发现,这就是在定义,且改变这
memory_end、main_memory_start、buffer_memory_end这三个变量的值;首先前面有句:#define EXT_MEM_K (*(unsigned short *)0x90002)在获取
memory_end的内存大小后面就是一些判断,判断内存的大小并初始化数据;代码有解释
实际上就是这三个变量
memory_end、main_memory_start、buffer_memory_end指向了不同的位置我们用内存为16MB来说明,有一张图来说明一哈

看看后面那一段init(初始化)代码,先看第一个
mem_init
1、第一个初始化函数,mem_init()
mem_init(main_memory_start,memory_end);
可以看出传入之前定义的那两个参数:main_memory_start、memory_end
mm 文件夹 memory.c
那先看看这个函数把:这个函数的位置在:linux文件下mm文件下的memory.c中
#define invalidate() \
__asm__("movl %%eax,%%cr3"::"a" (0))
/* these are not to be changed without changing head.s etc */
#define LOW_MEM 0x100000
#define PAGING_MEMORY (15*1024*1024) //15728640
#define PAGING_PAGES (PAGING_MEMORY>>12) //3840
#define MAP_NR(addr) (((addr)-LOW_MEM)>>12)
#define USED 100
#define CODE_SPACE(addr) ((((addr)+4095)&~4095) < \
current->start_code + current->end_code)
static long HIGH_MEMORY = 0;
#define copy_page(from,to) \
__asm__("cld ; rep ; movsl"::"S" (from),"D" (to),"c" (1024):"cx","di","si")
static unsigned char mem_map [ PAGING_PAGES ] = {0,};
//start_mem = 4MB end_mem = 16MB
void mem_init(long start_mem, long end_mem)
{
int i;
HIGH_MEMORY = end_mem; //前面定义:HIGH_MEMORY = 0 赋值为传入的参数end_mem
for (i=0 ; i<PAGING_PAGES ; i++) //PAGING_PAGES前面也有
mem_map[i] = USED; //前面的定义的一个char数组
i = MAP_NR(start_mem); //MAP_NR前面定义了 start_mem这个位置减去LOW_MEM,再右移12位
end_mem -= start_mem; //更改传入的参数end_mem = end_mem - start_mem
end_mem >>= 12; // end_mem右移动12位
while (end_mem-->0)
mem_map[i++]=0; //
}
如果传入的start_mem = 4MB end_mem = 16MB
HIGH_MEMORY = 4MB PAGING_PAGES = 3840B正好一个char型占1个字节也就是8位mem_map 数组的3840B全为100i = 768Bend_mem = 3072Bmem_map数组 从 768B 开始全部添加3840B个0使所以数组的长度为 3840 每个里面存4k数据的位置,正好为15MB
真相这些只是把数据存放在数组中,并不代表真实的内存
实际上就是
mem_map数组存储哪些内存有值,哪些没有为0可以使用最终就是 1-3MB为100值;3~16MB为0
正好
mem_map数组的前768存100,768~3840存0
看看下面这个图吧

linux-0.11分析:init文件 main.c的第一个初始化函数mem_int 第四篇随笔的更多相关文章
- linux-0.11分析:init文件 main.c的第二个初始化函数trap_init() 第五篇随笔
2.第二个初始化函数,trap_init() 参考 [github这个博主的 厉害][ https://github.com/sunym1993/flash-linux0.11-talk ] kern ...
- Linux 0.11下信号量的实现和应用
Linux 011下信号量的实现和应用 生产者-消费者问题 实现信号量 信号量的代码实现 关于sem_wait和sem_post sem_wait和sem_post函数的代码实现 信号量的完整代码 实 ...
- Linux 0.11源码阅读笔记-总览
Linux 0.11源码阅读笔记-总览 阅读源码的目的 加深对Linux操作系统的了解,了解Linux操作系统基本架构,熟悉进程管理.内存管理等主要模块知识. 通过阅读教复杂的代码,锻炼自己复杂项目代 ...
- Linux 0.11中write实现
看了一下Linux 0.11版本号write的实现,首先它在标准头文件unistd.h中有定义 int write(int fildes, const char * buf, off_t count) ...
- 【从头到脚品读 Linux 0.11 源码】第一回 最开始的两行代码
从这一篇开始,您就将跟着我一起进入这操作系统的梦幻之旅! 别担心,每一章的内容会非常的少,而且你也不要抱着很大的负担去学习,只需要像读小说一样,跟着我一章一章读下去就好. 话不多说,直奔主题.当你按下 ...
- Linux 0.11源码阅读笔记-总结
总结 Linux 0.11主要包含文件管理和进程管理两个部分.进程管理包括内存管理.进程管理.进程间通信模块.文件管理包含磁盘文件系统,打开文件内存数据.磁盘文件系统包括空闲磁盘块管理,文件数据块的管 ...
- Linux 0.11源码阅读笔记-文件管理
Linux 0.11源码阅读笔记-文件管理 文件系统 生磁盘 未安装文件系统的磁盘称之为生磁盘,生磁盘也可以作为文件读写,linux中一切皆文件. 磁盘分区 生磁盘可以被分区,分区中可以安装文件系统, ...
- Linux 0.11源码阅读笔记-中断过程
Linux 0.11源码阅读笔记-中断过程 是什么中断 中断发生时,计算机会停止当前运行的程序,转而执行中断处理程序,然后再返回原被中断的程序继续运行.中断包括硬件中断和软件中断,硬中断是由外设自动产 ...
- 分析入口文件main.php
在分析之前,需要了解php cli模式下的编程 1.了解getopt函数,php手册地址:http://php.net/manual/zh/function.getopt.php static pri ...
随机推荐
- Spring Boot整合模板引擎thymeleaf
项目结构 引入依赖pom.xml <!-- 引入 thymeleaf 模板依赖 --> <dependency> <groupId>org.springframew ...
- NoClassDefFoundError问题
问题: 遇到一个问题,报NoClassDefFoundError,如下图: NoClassDefFoundError和ClassNotFoundException区别 我们经常被java.lang.C ...
- 词云图value传递数据不显示(已解决)
问题描述: 今天在做词云图时,虽然词云图能够展现出来,但是后台传递过来的数据(每个词出现的次数)却不显示. 错误原因: 错误的将tooltip写在了series内部,如图: 解决方案: 将toolti ...
- Windows环境下启动Redis报错:Could not create server TCP listening socket 127.0.0.1:6379: bind: 操作成功完成。(已解决)
问题描述: 今天在windows环境下启动Redis时启动失败报错: 解决方案: ①运行命令:redis-cli.exe ②退出Redis ③运行命令:redis-server.exe redis.w ...
- 【FineBI】增量数据更新语句
SELECT * FROM t_abike_user WHERE AddUserTime BETWEEN '2016-11-17 10:49:04' AND '2021-07-31 23:59:59'
- 选择ERP频频踩雷?国内外ERP有差异,突破ERP软件单一性是关键
信息化日新月异的蓬勃发展,导致企业在选择ERP软件时频频踩雷.企业如何选择出一个适合自己的ERP软件系统呢?是选择国外知名公司的ERP软件产品,还是选择国内性价比高的ERP软件产品呢,小编就带大家了解 ...
- Aged-cat 的 WebServer 配置详细流程
前言 最近看到一个不错的webserver项目,但是配置过程给的不详细,这里给出详细配置过程 项目地址:https://github.com/Aged-cat/WebServer (感谢老猫大神的项目 ...
- django框架4
内容概要 编辑删除功能编写 虚拟环境 django路由层版本区别 视图函数的返回值 JsonResponse对象 form表单上传文件 request其他方法 FBV与CBV(基于函数的视图.基于类的 ...
- 模块re正则
正则表达式 内容概要 正则表达式前戏 正则表达式之字符组 正则表达式特殊符号 正则表达式量词 正则表达式贪婪与非贪婪匹配 正则表达式取消转义 python内置模块之re模块 内容详情 正则表达式前戏 ...
- 数位 dp 总结
数位 dp 总结 特征 问你一个区间 \([L,R]\) 中符合要求的数的个数 一个简单的 trick :把答案拆成前缀和 \(Ans(R)-Ans(L-1)\) 如何求 \(Ans()\) ,就要用 ...