177 lines
3.6 KiB
C
177 lines
3.6 KiB
C
/*
|
||
* 类型
|
||
*/
|
||
typedef int i32;
|
||
typedef unsigned int u32;
|
||
typedef short i16;
|
||
typedef unsigned short u16;
|
||
typedef char i8;
|
||
typedef unsigned char u8;
|
||
|
||
// 通常描述一个对象的大小,会根据机器的型号变化类型
|
||
typedef u32 size_t;
|
||
// elf文件格式会用
|
||
typedef u32 Elf32_Addr;
|
||
typedef u16 Elf32_Half;
|
||
typedef u32 Elf32_Off;
|
||
typedef i32 Elf32_Sword;
|
||
typedef u32 Elf32_Word;
|
||
|
||
/*
|
||
* elf相关
|
||
*/
|
||
#define KERNEL_ELF 0x80400
|
||
|
||
#define EI_NIDENT 16
|
||
typedef struct elf32_hdr {
|
||
unsigned char e_ident[EI_NIDENT];
|
||
Elf32_Half e_type;
|
||
Elf32_Half e_machine;
|
||
Elf32_Word e_version;
|
||
Elf32_Addr e_entry; /* Entry point */
|
||
Elf32_Off e_phoff;
|
||
Elf32_Off e_shoff;
|
||
Elf32_Word e_flags;
|
||
Elf32_Half e_ehsize;
|
||
Elf32_Half e_phentsize;
|
||
Elf32_Half e_phnum;
|
||
Elf32_Half e_shentsize;
|
||
Elf32_Half e_shnum;
|
||
Elf32_Half e_shstrndx;
|
||
} Elf32_Ehdr;
|
||
|
||
#define PT_NULL 0
|
||
#define PT_LOAD 1
|
||
#define PT_DYNAMIC 2
|
||
#define PT_INTERP 3
|
||
#define PT_NOTE 4
|
||
#define PT_SHLIB 5
|
||
#define PT_PHDR 6
|
||
|
||
typedef struct elf32_phdr {
|
||
Elf32_Word p_type;
|
||
Elf32_Off p_offset;
|
||
Elf32_Addr p_vaddr;
|
||
Elf32_Addr p_paddr;
|
||
Elf32_Word p_filesz;
|
||
Elf32_Word p_memsz;
|
||
Elf32_Word p_flags;
|
||
Elf32_Word p_align;
|
||
} Elf32_Phdr;
|
||
|
||
/*
|
||
* 显示相关
|
||
*/
|
||
#define TERMINAL_COLUMN 80
|
||
#define TERMINAL_ROW 25
|
||
|
||
#define TERMINAL_POS(row, column) ((u16)(row) * TERMINAL_COLUMN + (column))
|
||
/*
|
||
* 终端默认色,黑底白字
|
||
*/
|
||
#define DEFAULT_COLOR 0x0f00
|
||
|
||
/*
|
||
* 这个函数将content数据(2字节)写到终端第disp_pos个字符
|
||
* 第0个字符在0行0列,第1个字符在0行1列,第80个字符在1行0列,以此类推
|
||
* 用的是内联汇编,等价于mov word [gs:disp_pos * 2], content
|
||
*/
|
||
inline static void
|
||
write_to_terminal(u16 disp_pos, u16 content)
|
||
{
|
||
asm(
|
||
"mov %1, %%gs:(%0)" ::"r"(disp_pos * 2), "r"(content)
|
||
: "memory");
|
||
}
|
||
|
||
/*
|
||
* 清屏
|
||
*/
|
||
static void
|
||
clear_screen()
|
||
{
|
||
for (int i = 0; i < TERMINAL_ROW; i++)
|
||
for (int j = 0; j < TERMINAL_COLUMN; j++)
|
||
write_to_terminal(TERMINAL_POS(i, j),
|
||
DEFAULT_COLOR | ' ');
|
||
}
|
||
|
||
static void *
|
||
memset(void *v, int c, size_t n)
|
||
{
|
||
char *p;
|
||
int m;
|
||
|
||
p = v;
|
||
m = n;
|
||
while (--m >= 0)
|
||
*p++ = c;
|
||
|
||
return v;
|
||
}
|
||
|
||
static void *
|
||
memcpy(void *dst, const void *src, size_t n)
|
||
{
|
||
const char *s;
|
||
char *d;
|
||
|
||
s = src;
|
||
d = dst;
|
||
|
||
if (s < d && s + n > d) {
|
||
s += n;
|
||
d += n;
|
||
while (n-- > 0)
|
||
*--d = *--s;
|
||
} else {
|
||
while (n-- > 0)
|
||
*d++ = *s++;
|
||
}
|
||
|
||
return dst;
|
||
}
|
||
|
||
/*
|
||
* 初始化函数,加载kernel.bin的elf文件并跳过去。
|
||
*/
|
||
void
|
||
load_kernel()
|
||
{
|
||
clear_screen();
|
||
for (char *s = "----start loading kernel elf----", *st = s; *s; s++)
|
||
write_to_terminal(s - st, DEFAULT_COLOR | *s);
|
||
|
||
Elf32_Ehdr *kernel_ehdr = (Elf32_Ehdr *)KERNEL_ELF;
|
||
u32* elf_magic = (u32*)KERNEL_ELF;
|
||
if (*elf_magic != 0x464c457f) {
|
||
// make sure it's a elf file
|
||
for (char *s = "not a elf file", *st = s; *s; s++)
|
||
write_to_terminal(80 + s - st, DEFAULT_COLOR | *s);
|
||
while (1);
|
||
}
|
||
|
||
if (kernel_ehdr->e_machine != 0x03) {
|
||
for (char *s = "not a x86 executable", *st = s; *s; s++)
|
||
write_to_terminal(80 + s - st, DEFAULT_COLOR | *s);
|
||
while (1);
|
||
}
|
||
|
||
Elf32_Phdr *kernel_phdr = (void *)kernel_ehdr + kernel_ehdr->e_phoff;
|
||
for (u32 i = 0; i < kernel_ehdr->e_phnum; i++, kernel_phdr++)
|
||
{
|
||
if (kernel_phdr->p_type != PT_LOAD)
|
||
continue;
|
||
// 将elf的文件数据复制到指定位置
|
||
memcpy(
|
||
(void *)kernel_phdr->p_vaddr,
|
||
(void *)kernel_ehdr + kernel_phdr->p_offset,
|
||
kernel_phdr->p_filesz);
|
||
// 将后面的字节清零(p_memsz >= p_filesz)
|
||
memset(
|
||
(void *)kernel_phdr->p_vaddr + kernel_phdr->p_filesz,
|
||
0,
|
||
kernel_phdr->p_memsz - kernel_phdr->p_filesz);
|
||
}
|
||
((void (*)(void))(kernel_ehdr->e_entry))();
|
||
} |