init文件夹 mian.c

参考 [github这个博主的 厉害][ https://github.com/sunym1993/flash-linux0.11-talk ]

  1. 首先先看看这个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全为100

  • i = 768B

  • end_mem = 3072B

  • mem_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 第四篇随笔的更多相关文章

  1. linux-0.11分析:init文件 main.c的第二个初始化函数trap_init() 第五篇随笔

    2.第二个初始化函数,trap_init() 参考 [github这个博主的 厉害][ https://github.com/sunym1993/flash-linux0.11-talk ] kern ...

  2. Linux 0.11下信号量的实现和应用

    Linux 011下信号量的实现和应用 生产者-消费者问题 实现信号量 信号量的代码实现 关于sem_wait和sem_post sem_wait和sem_post函数的代码实现 信号量的完整代码 实 ...

  3. Linux 0.11源码阅读笔记-总览

    Linux 0.11源码阅读笔记-总览 阅读源码的目的 加深对Linux操作系统的了解,了解Linux操作系统基本架构,熟悉进程管理.内存管理等主要模块知识. 通过阅读教复杂的代码,锻炼自己复杂项目代 ...

  4. Linux 0.11中write实现

    看了一下Linux 0.11版本号write的实现,首先它在标准头文件unistd.h中有定义 int write(int fildes, const char * buf, off_t count) ...

  5. 【从头到脚品读 Linux 0.11 源码】第一回 最开始的两行代码

    从这一篇开始,您就将跟着我一起进入这操作系统的梦幻之旅! 别担心,每一章的内容会非常的少,而且你也不要抱着很大的负担去学习,只需要像读小说一样,跟着我一章一章读下去就好. 话不多说,直奔主题.当你按下 ...

  6. Linux 0.11源码阅读笔记-总结

    总结 Linux 0.11主要包含文件管理和进程管理两个部分.进程管理包括内存管理.进程管理.进程间通信模块.文件管理包含磁盘文件系统,打开文件内存数据.磁盘文件系统包括空闲磁盘块管理,文件数据块的管 ...

  7. Linux 0.11源码阅读笔记-文件管理

    Linux 0.11源码阅读笔记-文件管理 文件系统 生磁盘 未安装文件系统的磁盘称之为生磁盘,生磁盘也可以作为文件读写,linux中一切皆文件. 磁盘分区 生磁盘可以被分区,分区中可以安装文件系统, ...

  8. Linux 0.11源码阅读笔记-中断过程

    Linux 0.11源码阅读笔记-中断过程 是什么中断 中断发生时,计算机会停止当前运行的程序,转而执行中断处理程序,然后再返回原被中断的程序继续运行.中断包括硬件中断和软件中断,硬中断是由外设自动产 ...

  9. 分析入口文件main.php

    在分析之前,需要了解php cli模式下的编程 1.了解getopt函数,php手册地址:http://php.net/manual/zh/function.getopt.php static pri ...

随机推荐

  1. Spring Boot整合模板引擎thymeleaf

    项目结构 引入依赖pom.xml <!-- 引入 thymeleaf 模板依赖 --> <dependency> <groupId>org.springframew ...

  2. NoClassDefFoundError问题

    问题: 遇到一个问题,报NoClassDefFoundError,如下图: NoClassDefFoundError和ClassNotFoundException区别 我们经常被java.lang.C ...

  3. 词云图value传递数据不显示(已解决)

    问题描述: 今天在做词云图时,虽然词云图能够展现出来,但是后台传递过来的数据(每个词出现的次数)却不显示. 错误原因: 错误的将tooltip写在了series内部,如图: 解决方案: 将toolti ...

  4. 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 ...

  5. 【FineBI】增量数据更新语句

    SELECT * FROM t_abike_user WHERE AddUserTime BETWEEN '2016-11-17 10:49:04' AND '2021-07-31 23:59:59'

  6. 选择ERP频频踩雷?国内外ERP有差异,突破ERP软件单一性是关键

    信息化日新月异的蓬勃发展,导致企业在选择ERP软件时频频踩雷.企业如何选择出一个适合自己的ERP软件系统呢?是选择国外知名公司的ERP软件产品,还是选择国内性价比高的ERP软件产品呢,小编就带大家了解 ...

  7. Aged-cat 的 WebServer 配置详细流程

    前言 最近看到一个不错的webserver项目,但是配置过程给的不详细,这里给出详细配置过程 项目地址:https://github.com/Aged-cat/WebServer (感谢老猫大神的项目 ...

  8. django框架4

    内容概要 编辑删除功能编写 虚拟环境 django路由层版本区别 视图函数的返回值 JsonResponse对象 form表单上传文件 request其他方法 FBV与CBV(基于函数的视图.基于类的 ...

  9. 模块re正则

    正则表达式 内容概要 正则表达式前戏 正则表达式之字符组 正则表达式特殊符号 正则表达式量词 正则表达式贪婪与非贪婪匹配 正则表达式取消转义 python内置模块之re模块 内容详情 正则表达式前戏 ...

  10. 数位 dp 总结

    数位 dp 总结 特征 问你一个区间 \([L,R]\) 中符合要求的数的个数 一个简单的 trick :把答案拆成前缀和 \(Ans(R)-Ans(L-1)\) 如何求 \(Ans()\) ,就要用 ...