下载源码的文件夹,看到里面有以下内容:

解释一下里面都有啥

lib -> 共享代码
  1、libfs 文件系统(磁盘管理)
  2、liballoc 内存分配和虚拟内存映射(内存管理)
  3、libexec 程序代码和数据的处理及获取
  4、libmpi 并发编程的一些通信接口
  5、libipc 进程间通信接口
  6、libnet 一些标准网络协议的实现(网络驱动)
  7、libstd 算法和数据结构的模板
  8、libtest 测试框架
  9、libarch 与特定处理器相关的代码
  10、libposix 给应用层提供的标准系统调用接口
  11、libi2c 通信驱动(I/O设备)
  12、libusb 通信驱动(I/O设备)
  13、libspi 通信驱动(I/O设备)

kernel -> 内核代码,包含:进程调度,虚拟内存管理
  1、API(系统调用的接口及接口的内核侧实现)
  2、ARM、Intel 特定处理器下的内核代码(switching、bootupcode)

bin
  sh -> 命令行交互程序,用于执行外部程序和内置命令行;算是应用程序范畴

server -> 一些服务程序,作为操作系统的一些扩展组件。提供某些特定服务,设备驱动,文件系统等;

  usb
  video
  ...

config

  应该是放一些配置文件的地方

test

  测试相关

support

  支撑scons等开发工具相关的

====================================================

这里以intel处理器平台为例:

在/kernel/intel/pc/main.cpp中找到内核的main函数,这里应该是整个操作系统的入口函数。

Main函数如下:

 extern C int kernel_main(CoreInfo *info)
 {
     // Initialize heap at 3MB offset
     coreInfo.heapAddress = MegaByte();
     coreInfo.heapSize    = MegaByte();
     Kernel::heap(coreInfo.heapAddress, coreInfo.heapSize);

     // Start kernel debug serial console
     )
     {
         IntelSerial *serial = new IntelSerial(0x3f8);
         serial->setMinimumLogLevel(Log::Notice);
     }

     // Run all constructors first
     constructors();

     // Create and run the kernel
     IntelKernel *kernel = new IntelKernel(info);
     return kernel->run();
 }

第一步初始化heap,即初始化heap函数,它是Kernel类的静态函数。

该函数原型及注释如下:

/**
* Initialize heap.
*
* This function sets up the kernel heap for
* dynamic memory allocation with new() and delete()
* operators. It must be called before any object
* is created using new().
*
* @return Zero on success or error code on failure.
*/

static Error heap(Address base, Size size);

是建立内核堆,用于动态内存分配的,任何新对象的创建都必须在内核堆初始化之后进行。

第二步constructors

constructors是用来干嘛的?不是很清楚,后面再研究。。。

extern C void constructors()
{
    for (void (**ctor)() = &CTOR_LIST; *ctor; ctor++)
    {
        (*ctor)();
    }
}

存在于/kernel/Support.cpp中

第三步new kernel对象

info是有关内核配置信息的结构体,作为new kernel对象时构造函数的参数。info包含了一些内核初始化必要的信息。

接下来研究kernel对象kernel对象是IntelKernel类的实例,

相关类的继承关系如下所示:IntelKernel -> Kernel -> Singleton<Kernel>(这些类的详细定义有待后续研究)

new出kernel对象后,就运行了对象的run方法,该方法在Kernel中有定义,IntelKernel中没有。run方法定义如下:

int Kernel::run()
{
    NOTICE("");

    // Load boot image programs
    loadBootImage();

    // Start the scheduler
    m_procs->getScheduler()->setTimer(m_timer);
    m_procs->schedule();

    // Never actually returns.
    ;
}

run函数做了两件事情:

1)加载bootImage。这是一个程序,具体做啥的不清楚,有待研究。加载过程需要分析loadBootImage()函数,有待研究,这个是kernel的成员函数。

2)给调度器Scheduler设置定时器setTimer(),启动进程调度schedule()。

  m_procs是kernel的成员变量,指向进程管理器这个类的指针,有待研究一下。

  

  进程管理器调用getScheduler()成员函数,返回的是指向调度器对象的指针,m_scheduler。

  

  

  调度器Scheduler这个类有待研究。

  

  调度器Scheduler使用了其成员函数setTimer()。

  

  Timer也是一个类,有待研究。

====================================================

其实我们忽略了一些重要的内容,就是分析一下IntelKernel的构造函数,及Kernel的构造函数,还有就是探究Singleton<>这个模板类。

以下是IntelKernel的构造函数:

IntelKernel::IntelKernel(CoreInfo *info)
    : Kernel(info)
{

    IntelMap map;
    IntelCore core;
    IntelPaging memContext(&map, core.readCR3(), m_alloc);

    // Refresh MemoryContext::current()
    memContext.activate();

    // Install interruptRun() callback
    interruptRun = ::executeInterrupt;

    // Setup exception handlers
    ; i < ; i++)
    {
        hookIntVector(i, exception, );
    }
    // Setup IRQ handlers
    ; i < ; i++)
    {
        // Trap gate
        if (i == 0x90)
            hookIntVector();

        // Hardware Interrupt
        else
            hookIntVector(i, interrupt, );
    }

    // Only core0 uses PIC and PIT.
    )
    {
        // Set PIT interrupt frequency to 250 hertz
        m_pit.setFrequency();

        // Configure the master and slave PICs
        m_pic.initialize();
        m_intControl = &m_pic;
    }
    else
        m_intControl = ;

    // Try to configure the APIC.
    if (m_apic.initialize() == Timer::Success)
    {
        NOTICE("Using APIC timer");

        // Enable APIC timer interrupt
        hookIntVector(m_apic.getInterrupt(), clocktick, );

        m_timer = &m_apic;

        )
        {
            m_apic.start(&m_pit);
            m_coreInfo->timerCounter = m_apic.getCounter();
        }
        else
            m_apic.start(m_coreInfo->timerCounter, m_pit.getFrequency());
    }
    // Use PIT as system timer.
    else
    {
        NOTICE("Using PIT timer");
        m_timer = &m_pit;

        // Install PIT interrupt vector handler
        hookIntVector(m_intControl->getBase() +
                      m_pit.getInterrupt(), clocktick, );

        // Enable PIT interrupt
        enableIRQ(m_pit.getInterrupt(), true);
    }

    // Initialize TSS Segment
    Address tssAddr = (Address) &kernelTss;
    gdt[KERNEL_TSS].limitLow    = );
    gdt[KERNEL_TSS].baseLow     = (tssAddr) & 0xffff;
    gdt[KERNEL_TSS].baseMid     = (tssAddr >> ) & 0xff;
    gdt[KERNEL_TSS].type        = ;
    gdt[KERNEL_TSS].privilege   = ;
    gdt[KERNEL_TSS].present     = ;
    gdt[KERNEL_TSS].limitHigh   = ;
    gdt[KERNEL_TSS].granularity = ;
    gdt[KERNEL_TSS].baseHigh    = (tssAddr >> ) & 0xff;

    // Fill the Task State Segment (TSS).
    MemoryBlock::, sizeof(TSS));
    kernelTss.ss0    = KERNEL_DS_SEL;
    kernelTss.esp0   = ;
    kernelTss.bitmap = sizeof(TSS);
    ltr(KERNEL_TSS_SEL);
}

然后是Kernel的构造函数:

Kernel::Kernel(CoreInfo *info)
    : Singleton<Kernel>()
{
    // Output log banners
    if (Log::instance)
    {
        Log::instance->append(BANNER);
        Log::instance->append(COPYRIGHT "\r\n");
    }

    // Compute lower & higher memory
    Memory::Range highMem;
    Arch::MemoryMap map;
    MemoryBlock::, sizeof(highMem));
    highMem.phys = info->memory.phys + map.range(MemoryMap::KernelData).size;

    // Initialize members
    m_alloc  = new SplitAllocator(info->memory, highMem);
    m_procs  = new ProcessManager(new Scheduler());
    m_api    = new API();
    m_coreInfo   = info;
    m_intControl = ZERO;
    m_timer      = ZERO;

    // Mark kernel memory used (first 4MB in phys memory)
    ; i < info->kernel.size; i += PAGESIZE)
        m_alloc->allocate(info->kernel.phys + i);

    // Mark BootImage memory used
    ; i < m_coreInfo->bootImageSize; i += PAGESIZE)
        m_alloc->allocate(m_coreInfo->bootImageAddress + i);

    // Mark heap memory used
    ; i < m_coreInfo->heapSize; i += PAGESIZE)
        m_alloc->allocate(m_coreInfo->heapAddress + i);

    // Reserve CoreChannel memory
    ; i < m_coreInfo->coreChannelSize; i += PAGESIZE)
        m_alloc->allocate(m_coreInfo->coreChannelAddress + i);

    // Clear interrupts table
    m_interrupts.fill(ZERO);
}

子类构造函数运行前会先运行其父类的构造函数。所以应该是Kernel的构造函数先执行,然后是IntelKernel的构造函数。

一、分析Kernel的构造函数

  1)涉及到low&higher memory的知识

   Linux high memory 学习总结:https://www.cnblogs.com/kerrycode/p/5200843.html

   linux内核的high memory概念详解:https://blog.csdn.net/acs713/article/details/8575235

  2)主要过程

    计算 low&higher memory

    初始化成员(allocator、processmanager、中断管理器、定时器、内核信息)

      探究类:SplitAllocator->Allocator、ProcessManager、IntController、Timer;

    分配内存(这部分我的理解是为物理内存中内核镜像建立映射到虚拟内存中),讲得不是很清楚,需要理解allocator。

    

二、分析IntelKernel的构造函数

    1)定义了map、mapcontext类的实例(MemoryMap、 MemoryContextl类有待研究)

  2)建立中断、异常、陷阱的处理函数

  3) PIC和PIT的初始化,PIC是外部中断处理器,PIT是外部中断定时器;还有一种APIC不是很清楚,有待研究

    PIC简介:https://www.jianshu.com/p/16bf6aaa1ade

  4) TSS 任务状态段的初始化

    TSS介绍:https://www.cnblogs.com/long123king/p/3501853.html

    linux内核-TSS:https://www.cnblogs.com/ISeeIC/p/3617573.html

FreeNOS学习3——了解目录结构和Main函数的更多相关文章

  1. Magento学习第一课——目录结构介绍

    Magento学习第一课--目录结构介绍 一.Magento为何强大 Magento是在Zend框架基础上建立起来的,这点保证了代码的安全性及稳定性.选择Zend的原因有很多,但是最基本的是因为zen ...

  2. thinkphp学习笔记1—目录结构和命名规则

    原文:thinkphp学习笔记1-目录结构和命名规则 最近开始学习thinkphp,在下不才,很多的问题看不明白所以想拿出来,恕我大胆发在首页上,希望看到的人能为我答疑解惑,这样大家有个互动,学起来快 ...

  3. android学习——项目的目录结构

    学习开发之前要了解工程目录下的文件夹下文件的用意,是以HelloWorld为例: 1.HelloWorld项目的目录结构 1.1.src文件夹 1.2.gen文件夹 1.3.Android 2.1文件 ...

  4. python学习day4软件目录结构规范

    为什么要设计好目录结构? 参考:http://www.cnblogs.com/alex3714/articles/5765046.html "设计项目目录结构",就和"代 ...

  5. NDK学习二: NDK目录结构

    NDK目录结构   NDK下载好之后目录结构如下:         目录名 描述 build   存放和编译相关的脚本文件,最外面的ndk-build就是调用该目录下的makefile文件,其中mak ...

  6. Vue学习(一)Vue目录结构

    安装教程网上一大把,可以自己搜索.记录下学习过程. 认识下Vue的目录结构,取自:https://www.cnblogs.com/dragonir/p/8711761.html vue 文件目录结构详 ...

  7. Solr6.7 学习笔记(01) -- 目录结构

    Solr解压后的目录结构 --contrib: Solr的一些扩展 --analysis-extras: 包含一些文本分析组件及其依赖 --clustering: 包含一个用于集群搜索结果的引擎 -- ...

  8. python学习笔记:目录结构

    "项目目录结构"其实也是属于"可读性和可维护性"的范畴. 目录组织方式 关于如何组织一个较好的Python工程目录结构,已经有一些得到了共识的目录结构.在Sta ...

  9. Nuxt.js学习(二) --- Nuxt目录结构详解、Nuxt常用配置项、Nuxt路由配置和参数传递

    [TOC] 1.Nuxt目录结构详解 Nuxt项目文件目录结构 |-- .nuxt // Nuxt自动生成,临时的用于编辑的文件,build |-- assets // 用于组织未编译的静态资源入LE ...

随机推荐

  1. GDB调试命令手册

    使用GDB 启动 $ gdb program           # program是你的可执行文件,一般在当前目录 $ gdb program core      # gdb同时调试运行程序和cor ...

  2. 【UTR #1】ydc的大树

    [UTR #1]ydc的大树 全网唯一一篇题解我看不懂 所以说一下我的O(nlogn)做法: 以1号点为根节点 一个黑点如果有多个相邻的节点出去都能找到最远的黑点,那么这个黑点就是无敌的 所以考虑每个 ...

  3. 【转载】Ubuntu终端常用的快捷键

    Ubuntu中的许多操作在终端(Terminal)中十分的快捷,记住一些快捷键的操作更得心应手.在Ubuntu中打开终端的快捷键是Ctrl+Alt+T.其他的一些常用的快捷键如下: 快捷键 功能 Ta ...

  4. 冒泡排序&&选择排序 以及时间效率对比

    package com.test4; import java.util.*; //Calendar 显示时间 /** * @author qingfeng * 功能:冒泡排序 */ public cl ...

  5. UIImageView xib里面拉伸图片技巧

    拉伸图片的时候代码里和xib里面的图片名字去掉@2x,但是原始图片文件得要xxx@2x.png The X and Y values seem to be the positions for the ...

  6. day2_python之文件操作

    一.文件常用操作 #1. 打开文件的模式有(默认为文本模式): r ,只读模式[默认模式,文件必须存在,不存在则抛出异常] w,只写模式[不可读:不存在则创建:存在则清空内容] a, 之追加写模式[不 ...

  7. E - Count on a tree 树上第K小

    主席树的入门题目,这道题的题意其实就是说,给你一棵树,询问在两个节点之间的路径上的区间第K小 我们如何把树上问题转换为区间问题呢? 其实DFS就可以,我们按照DFS的顺序,对线段树进行建树,那么这个树 ...

  8. SuperSocket 服务器管理器 (ServerManager)

    SuperSocket服务器管理器文档 客户端安全证书验证 在 TLS/SSL 安全通信中, 客户端的安全证书不是必需的, 但是有些系统需要更高级别的安全保障. 因此有些用户提出了在服务器端验证客户端 ...

  9. laravel 授权使用gate门类

    第一:先注册 第二:使用方式三种 路由中:Route::group(['middleware'=>'can:system'],function() {}) 模板中:@can("syst ...

  10. 用mysql查询某字段是否有索引

    可以使用SHOW INDEX FROM table_name来查看表的索引,从而查看字段的索引:查询结果中table为表名,key_name为索引名,Column_name为列名