Kernel.h 文件分析
关键成员变量
/** 物理内存分配器 */
SplitAllocator *m_alloc;
/** 进程管理器 */
ProcessManager *m_procs;
/** API管理器*/
API *m_api;
/** 针对当前Core的Coreinfo */
CoreInfo *m_coreInfo;
/** CPU打断管理器列表 */
Vector *> m_interrupts;
/** 打断管理器 */
IntController *m_intControl;
/** 计时器 */
Timer *m_timer;
构造和析构函数
-
kernel()
类的构造函数
-
Kernel(CoreInfo *info)
自定义的构造函数的实现
Kernel::Kernel(CoreInfo *info)
: Singleton
{
// 打印输出
if (Log::instance)
{
Log::instance->append(BANNER);
Log::instance->append(COPYRIGHT "\r\n");
}
// 计算最大和最小的内存
Memory::Range highMem;
Arch::MemoryMap map;
MemoryBlock::set(&highMem, 0, sizeof(highMem));
highMem.phys = info->memory.phys + map.range(MemoryMap::KernelData).size;
// 初始化成员变量
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;
// 标记kernel使用的内存位置(前4MB的物理内存)
for (Size i = 0; i < info->kernel.size; i += PAGESIZE)
m_alloc->allocate(info->kernel.phys + i);
// 标记BootImage使用的内存位置
for (Size i = 0; i < m_coreInfo->bootImageSize; i += PAGESIZE)
m_alloc->allocate(m_coreInfo->bootImageAddress + i);
// 储存核心信道的内存
for (Size i = 0; i < m_coreInfo->coreChannelSize; i += PAGESIZE)
m_alloc->allocate(m_coreInfo->coreChannelAddress + i);
// 清空打断列表
m_interrupts.fill(ZERO);
}
3. `~kernel()` 析构函数
### 处理CPU打断事件处理
代码定义了`void InterruptHandler(struct CPUState *state, ulong param)`函数来实现处理CPU打断事件并且在此基础上定义了名为`InterruptHook`的一个结构体,作为钩子使用;
typedef struct InterruptHook
{
/**
* Constructor function.
* @param h Handler function for the hook.
* @param p Parameter to pass.
*/
InterruptHook(InterruptHandler *h, ulong p) : handler(h), param(p)
{
}
/**
* Comparision operator.
* @param i InterruptHook pointer.
* @return True if equal, false otherwise.
*/
bool operator == (InterruptHook *i)
{
return handler == i->handler && param == i->param;
}
/** Executed at time of interrupt. */
InterruptHandler *handler;
/** Passed to the handler. */
ulong param;
}
InterruptHook;
### 对象方法
根据FreeNOS Document的知道有一些比较重要的方法
1. `void Kernel::enableIRQ(u32 irq, bool enabled)`
打开或关闭硬件打断(IRQ)功能, enabled is YES 打开。
2. `Kernel::Result Kernel::loadBootProcess(BootImage *image, Address imagePAddr, Size index)`
为BootProcess创建一个新的进程
以下是该方法的实现方法:
Kernel::Result Kernel::loadBootProcess(BootImage *image, Address imagePAddr, Size index)
{
Address imageVAddr = (Address) image, args;
Size args_size = ARGV_SIZE;
BootSymbol *program;
BootSegment *segment;
Process *proc;
char *vaddr;
Arch::MemoryMap map;
// Point to the program and segments table
program = &((BootSymbol *) (imageVAddr + image->symbolTableOffset))[index];
segment = &((BootSegment *) (imageVAddr + image->segmentsTableOffset))[program->segmentsOffset];
// Ignore non-BootProgram entries
if (program->type != BootProgram)
return InvalidBootImage;
// Create process
proc = m_procs->create(program->entry, map);
if (!proc)
{
FATAL("failed to create boot program: " << program->name);
return ProcessError;
}
proc->setState(Process::Ready);
// Obtain process memory
MemoryContext *mem = proc->getMemoryContext();
// Map program segment into it's virtual memory
for (Size i = 0; i < program->segmentsCount; i++)
{
for (Size j = 0; j < segment[i].size; j += PAGESIZE)
{
mem->map(segment[i].virtualAddress + j,
imagePAddr + segment[i].offset + j,
Memory::User |
Memory::Readable |
Memory::Writable |
Memory::Executable);
}
}
// Map program arguments into the process
// TODO: move into the high memory???
m_alloc->allocateLow(args_size, &args);
mem->map(ARGV_ADDR, args, Memory::User | Memory::Readable | Memory::Writable);
// Copy program arguments
vaddr = (char *) m_alloc->toVirtual(args);
MemoryBlock::set(vaddr, 0, PAGESIZE);
MemoryBlock::copy(vaddr, program->name, ARGV_SIZE);
// Done
NOTICE("loaded: " << program->name);
return Success;
}