79 lines
2.1 KiB
C
79 lines
2.1 KiB
C
|
||
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||
start.c
|
||
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||
Forrest Yu, 2005
|
||
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
|
||
|
||
#include "stdio.h"
|
||
#include "protect.h"
|
||
#include "proc.h"
|
||
#include "global.h"
|
||
#include "proto.h"
|
||
|
||
#include "assert.h"
|
||
#include "string.h"
|
||
|
||
/*
|
||
* 当发生不可挽回的错误时就打印错误信息并使CPU核休眠
|
||
*/
|
||
void _panic(const char *file, int line, const char *fmt, ...)
|
||
{
|
||
va_list ap;
|
||
|
||
// 确保CPU核不受外界中断的影响
|
||
asm volatile("cli");
|
||
asm volatile("cld");
|
||
|
||
va_start(ap, fmt);
|
||
kprintf("kernel panic at %s:%d: ", file, line);
|
||
vkprintf(fmt, ap);
|
||
kprintf("\n");
|
||
va_end(ap);
|
||
// 休眠CPU核,直接罢工
|
||
while (1)
|
||
asm volatile("hlt");
|
||
}
|
||
|
||
/*
|
||
* 很像panic,但是不会休眠CPU核,就是正常打印信息
|
||
*/
|
||
void _warn(const char *file, int line, const char *fmt, ...)
|
||
{
|
||
va_list ap;
|
||
|
||
va_start(ap, fmt);
|
||
kprintf("\x1b[47;93mkernel warning at %s:%d: \x1b[m", file, line);
|
||
vkprintf(fmt, ap);
|
||
kprintf("\n");
|
||
va_end(ap);
|
||
}
|
||
|
||
/*======================================================================*
|
||
cstart
|
||
*======================================================================*/
|
||
void cstart()
|
||
{
|
||
kprintf("-----\"cstart\" begins-----\n");
|
||
|
||
// 将 LOADER 中的 GDT 复制到新的 GDT 中
|
||
memcpy(&gdt, // New GDT
|
||
(void *)(*((u32 *)(&gdt_ptr[2]))), // Base of Old GDT
|
||
*((u16 *)(&gdt_ptr[0])) + 1 // Limit of Old GDT
|
||
);
|
||
// gdt_ptr[6] 共 6 个字节:0~15:Limit 16~47:Base。用作 sgdt 以及 lgdt 的参数。
|
||
u16 *p_gdt_limit = (u16 *)(&gdt_ptr[0]);
|
||
u32 *p_gdt_base = (u32 *)(&gdt_ptr[2]);
|
||
*p_gdt_limit = GDT_SIZE * sizeof(DESCRIPTOR) - 1;
|
||
*p_gdt_base = (u32)&gdt;
|
||
|
||
// idt_ptr[6] 共 6 个字节:0~15:Limit 16~47:Base。用作 sidt 以及 lidt 的参数。
|
||
u16 *p_idt_limit = (u16 *)(&idt_ptr[0]);
|
||
u32 *p_idt_base = (u32 *)(&idt_ptr[2]);
|
||
*p_idt_limit = IDT_SIZE * sizeof(GATE) - 1;
|
||
*p_idt_base = (u32)&idt;
|
||
|
||
init_prot();
|
||
|
||
kprintf("-----\"cstart\" finished-----\n");
|
||
} |