FreeNOS学习3——了解目录结构和Main函数
下载源码的文件夹,看到里面有以下内容:

解释一下里面都有啥

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函数的更多相关文章
- Magento学习第一课——目录结构介绍
Magento学习第一课--目录结构介绍 一.Magento为何强大 Magento是在Zend框架基础上建立起来的,这点保证了代码的安全性及稳定性.选择Zend的原因有很多,但是最基本的是因为zen ...
- thinkphp学习笔记1—目录结构和命名规则
原文:thinkphp学习笔记1-目录结构和命名规则 最近开始学习thinkphp,在下不才,很多的问题看不明白所以想拿出来,恕我大胆发在首页上,希望看到的人能为我答疑解惑,这样大家有个互动,学起来快 ...
- android学习——项目的目录结构
学习开发之前要了解工程目录下的文件夹下文件的用意,是以HelloWorld为例: 1.HelloWorld项目的目录结构 1.1.src文件夹 1.2.gen文件夹 1.3.Android 2.1文件 ...
- python学习day4软件目录结构规范
为什么要设计好目录结构? 参考:http://www.cnblogs.com/alex3714/articles/5765046.html "设计项目目录结构",就和"代 ...
- NDK学习二: NDK目录结构
NDK目录结构 NDK下载好之后目录结构如下: 目录名 描述 build 存放和编译相关的脚本文件,最外面的ndk-build就是调用该目录下的makefile文件,其中mak ...
- Vue学习(一)Vue目录结构
安装教程网上一大把,可以自己搜索.记录下学习过程. 认识下Vue的目录结构,取自:https://www.cnblogs.com/dragonir/p/8711761.html vue 文件目录结构详 ...
- Solr6.7 学习笔记(01) -- 目录结构
Solr解压后的目录结构 --contrib: Solr的一些扩展 --analysis-extras: 包含一些文本分析组件及其依赖 --clustering: 包含一个用于集群搜索结果的引擎 -- ...
- python学习笔记:目录结构
"项目目录结构"其实也是属于"可读性和可维护性"的范畴. 目录组织方式 关于如何组织一个较好的Python工程目录结构,已经有一些得到了共识的目录结构.在Sta ...
- Nuxt.js学习(二) --- Nuxt目录结构详解、Nuxt常用配置项、Nuxt路由配置和参数传递
[TOC] 1.Nuxt目录结构详解 Nuxt项目文件目录结构 |-- .nuxt // Nuxt自动生成,临时的用于编辑的文件,build |-- assets // 用于组织未编译的静态资源入LE ...
随机推荐
- 【JZOJ4861】【NOIP2016提高A组集训第7场11.4】推冰块
题目描述 Dpstr最近迷上了推冰块.冰地是一个n行m列的网格区域,第i行第j列的格子记为(i,j),也就是左上角为(1,1),右下角为(n,m).每个格子可能是冰面.障碍物.减速带三者之一.其中,冰 ...
- padas操作
1.从excel读取数据 pd.read_excel('naifen.xlsx') 2.保存为excel pd.to_excel('bb.xlsx') 3.统计某一列重复数据 df.groupby([ ...
- 【windows系统下的navicat与ubuntu中的mysql的连接方法】
##红色代码直接复制到终端 1.首先,终端上mysql -u root -p,进入你的mysql数据库,操作数据库use mysql.2.切换root权限:sudo -i3.对root授权,输入:gr ...
- 详解 CALayer 和 UIView 的区别和联系
http://www.cocoachina.com/ios/20150828/13244.html 作者:@武蕴牛x 授权本站转载. 前言 前面发了一篇iOS 面试的文章,在说到 UIView 和 C ...
- Java练习 SDUT-2499_数字
数字 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 定义f(x) = {比x小,不可以被x整除并且不和x互质的数的个数 ...
- TIJ——Chapter Four:Controlling Execution
同上一章,本章依然比较简单.基础,因此只是做一些总结性的笔记. 1. 不像C和C++那样(0是假,非零为真),Java不允许用一个数字作为boolean值. 2. C中,为了给变量分配空间,所有变量的 ...
- [***]沙雕低错集(算起来因为低错挂掉的分快够我AK三场了……)
由于沙雕错太多了所以不想写了,看着就难受…… 各种沙雕错(自从上次考试开始各种犯沙雕低错……): !!!sort是不稳定的排序,如果排序结构题只按其中一个关键字排序,那么在关键字相等时,排序多次的结果 ...
- int 和bigint差别有多大?
https://bbs.csdn.net/wap/topics/230059600 请问在mysql中int和bigint差别有多大?在什么情况下需要用到bigint? bigint 带符号的范围是- ...
- 巨蟒python全栈开发-第11阶段 ansible_project6
今日大纲: 1.计划任务前端页面 2.计划任务新增实现 3.计划任务编辑 4.项目详情 5.文件上传 6.replace模块介绍 1.计划任务前端页面 2.计划任务新增实现 3.计划任务编辑 4.项目 ...
- 03搭建docker私有仓库
搭建docker私仓,可以使用docker官方提供的registry镜像.该镜像目前有2.0,2.3和2.3.1版本.它只与1.6.0以上版本的docker兼容.搭建私仓的步骤如下: 一:无代理.无认 ...