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. Android.mk编译App源码

    在Andriod源码环境编译APP主要考虑如何引入第三方jar包和arr包的问题,初次尝试,步步是坑,这里给出一个模板: LOCAL_PATH := $(call my-dir) include $( ...

  2. Yaml中特殊符号"| > |+ |-"的作用

    "|",保留每行尾部的换行符\n. ">",删除每行尾部的换行符\n,则看似多行文本,则在程序中会将其视为一行. include_newlines: | ...

  3. flex布局的总结

    1.开启了flex布局的元素叫: flex container 2.里面的直接子元素叫:flex items(默认情况下,所有item都会在一行显示) 3.display属性由flex和inline- ...

  4. 基于bat脚本的前端发布流程设计与实现

    写在前面 本文大致向读者介绍了楼下几点知识,希望在编写bat脚本时候能够帮到读者,如果能够有所启迪,那就更好了. bat脚本的相关知识和案例编写 用windows自带的命令压缩文件 windows和l ...

  5. RocketMQ事务消息机制

    1.half消息对消费者不可见,用于确定MQ服务正常. 2.MQ响应half消息. 3.生产者执行本地事务. 4.生产者发送具体消息+本地事务状态,MQ根据本地事务状态执行Commit或者Rollba ...

  6. 基于thinkphp6 layui的优秀极速后台开发框架推荐

    很多时候我们在做项目开发的时候,苦于没有好一点的轮子,自己动手开发的话,太耗费时间了,如果采用VUE的话,学习成本跟调试也比较麻烦, 而且有时候选用的东西甲方也不太容易接受,现在给大家介绍一款优秀的极 ...

  7. Linux文本三剑客-sed

    sed工作原理: sed: Stream Editor.流编辑器 --- 属于行编辑工具 sed和vim一样都是文本编辑工具. 行编辑工具:一行一行处理文件内容 全屏编辑工具:一次性将文件内容加载到内 ...

  8. NC14731 逆序对

    NC14731 逆序对 题目 题目描述 求所有长度为 \(n\) 的 \(01\) 串中满足如下条件的二元组个数: 设第 \(i\) 位和第 \(j\) 位分别位 \(a_i\) 和 \(a_j\) ...

  9. NC16561 [NOIP2012]国王的游戏

    NC16561 [NOIP2012]国王的游戏 题目 题目描述 恰逢 H 国国庆,国王邀请 \(n\) 位大臣来玩一个有奖游戏.首先,他让每个大臣在左.右手上面分别写下一个整数,国王自己也在左.右手上 ...

  10. 让你的Nginx支持分布式追踪

    Background NGINX 是一个通用且流行的应用程序.也是最流行的 Web 服务器,它可用于提供静态文件内容,但也通常与其他服务一起用作分布式系统中的组件,在其中它用作反向代理.负载均衡 或 ...