forked from arceos-org/arceos
-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
25 changed files
with
1,553 additions
and
48 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
OUT ?= out | ||
|
||
entry-src := entry.S | ||
entry-obj := $(OUT)/entry.o | ||
loader-src := loader.c | ||
loader-obj := $(OUT)/loader.o | ||
virt-int-src := virt_int.S | ||
virt-int-obj := $(OUT)/virt_int.o | ||
virt-int-c-src := virt_int.c | ||
virt-int-c-obj := $(OUT)/virt_int_c.o | ||
|
||
ldscript := vlbl.lds | ||
target := $(OUT)/vlbl | ||
target-objs := $(entry-obj) $(loader-obj) $(virt-int-obj) $(virt-int-c-obj) | ||
target-elf := $(target).elf | ||
target-bin := $(target).bin | ||
target-disasm-16 := $(target).16.asm | ||
target-disasm-32 := $(target).32.asm | ||
|
||
CC ?= gcc | ||
AS ?= as | ||
LD ?= ld | ||
OBJCOPY ?= objcopy | ||
OBJDUMP ?= objdump | ||
|
||
all: $(OUT) $(target).bin disasm | ||
|
||
disasm: disasm16 disasm32 | ||
|
||
disasm16: | ||
$(OBJDUMP) -D -m i8086 -M intel $(target-elf) > $(target-disasm-16) | ||
|
||
disasm32: | ||
$(OBJDUMP) -D -m i386 -M intel $(target-elf) > $(target-disasm-32) | ||
|
||
$(OUT): | ||
mkdir -p $(OUT) | ||
|
||
$(entry-obj): $(entry-src) | ||
$(AS) --32 -msyntax=intel -mnaked-reg $< -o $@ | ||
|
||
$(loader-obj): $(loader-src) | ||
$(CC) -m32 -fno-pie -fno-builtin -Os -c $< -o $@ | ||
|
||
$(virt-int-obj): $(virt-int-src) | ||
$(AS) --32 -msyntax=intel -mnaked-reg $< -o $@ | ||
|
||
$(virt-int-c-obj): $(virt-int-c-src) | ||
$(CC) -m16 -march=i386 -fno-pie -fno-builtin -Os -c $< -o $@ | ||
|
||
$(target-elf): $(target-objs) $(ldscript) | ||
$(LD) -T$(ldscript) $(target-objs) -o $@ | ||
|
||
$(target-bin): $(target-elf) | ||
$(OBJCOPY) $< --strip-all -O binary $@ | ||
|
||
clean: | ||
rm -rf $(OUT) | ||
|
||
.PHONY: all disasm clean |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
/* as we do not have 64-bit codes here, it's safe to assume that */ | ||
typedef unsigned char uint8_t, *uint8_p; | ||
typedef unsigned short int uint16_t, *uint16_p; | ||
typedef unsigned long int uint32_t, *uint32_p; | ||
typedef signed char int8_t, *int8_p; | ||
typedef signed short int int16_t, *int16_p; | ||
typedef signed long int int32_t, *int32_p; | ||
|
||
#ifndef bool | ||
typedef uint8_t bool; | ||
# define true (1) | ||
# define false (0) | ||
#endif | ||
|
||
static inline void outb(uint8_t value, uint16_t port) { | ||
asm volatile("outb %b0, %w1" : : "a"(value), "Nd"(port)); | ||
} | ||
|
||
#define COM1 0x3f8 | ||
static inline void putchar(char c) { | ||
outb((uint8_t)c, COM1); | ||
} | ||
|
||
static inline void putsi(const char *s) { | ||
while (*s != '\0') { | ||
putchar(*(s++)); | ||
} | ||
} | ||
|
||
static inline void puts(const char *s) { | ||
putsi(s); | ||
putchar('\n'); | ||
} | ||
|
||
static inline void putud(uint32_t num) { | ||
static char buf[12]; | ||
int8_t cnt = 0; | ||
while (num > 0) { | ||
buf[cnt++] = '0' + num % 10; | ||
num /= 10; | ||
} | ||
|
||
while (--cnt >= 0) { | ||
putchar(buf[cnt]); | ||
} | ||
} | ||
|
||
static inline void putux(uint32_t num, bool prefix, int8_t padding) { | ||
static char buf[10]; | ||
const char *chars = "0123456789abcdef"; | ||
int8_t cnt = 0; | ||
while (num > 0) { | ||
buf[cnt++] = chars[num % 16]; | ||
num /= 16; | ||
} | ||
|
||
if (padding > cnt && padding <= 10) { | ||
while (cnt < padding) { | ||
buf[cnt++] = '0'; | ||
} | ||
} | ||
|
||
if (prefix) { | ||
putchar('0'); | ||
putchar('x'); | ||
} | ||
|
||
while (--cnt >= 0) { | ||
putchar(buf[cnt]); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
# it's 7c00 here | ||
.section .text | ||
.code16 | ||
.global entry | ||
entry: | ||
cli | ||
cld | ||
|
||
# 初始化段寄存器 | ||
xor ax, ax | ||
mov ds, ax | ||
mov es, ax | ||
mov ss, ax | ||
|
||
# 进入保护模式 | ||
lgdt [prot_gdt_desc] | ||
mov eax, cr0 | ||
or eax, 0x1 | ||
mov cr0, eax | ||
|
||
ljmp 0x8, entry32 | ||
|
||
.code32 | ||
.global entry32 | ||
entry32: | ||
# 初始化段选择子到数据段 | ||
mov ax, 0x10 | ||
mov ds, ax | ||
mov es, ax | ||
mov ss, ax | ||
mov fs, ax | ||
mov gs, ax | ||
|
||
# 初始化临时栈 | ||
mov ebp, 0x7b00 | ||
mov esp, 0x7b00 | ||
|
||
# 加载内核 | ||
push 0x00100000 # 32-bit 加载地址 | ||
push 0x0001e000 # 栈顶地址 | ||
push 0x00010000 # 16-bit 加载地址 | ||
push 0x70200000 # 镜像地址 | ||
call load_kernel | ||
|
||
# 跳转到16-bit保护模式 | ||
lgdt [prot_16_gdt_desc] | ||
ljmp 0x8, entry_prot_16 | ||
|
||
|
||
.code16 | ||
.global entry_prot_16 | ||
entry_prot_16: | ||
# 再次初始化段选择子到数据段 | ||
mov ax, 0x10 | ||
mov ds, ax | ||
mov es, ax | ||
mov ss, ax | ||
mov fs, ax | ||
mov gs, ax | ||
|
||
# 加载中断向量表 | ||
lidt [real_idt_dest] | ||
|
||
# 关闭保护模式 | ||
mov eax, cr0 | ||
or eax, 0x1 | ||
xor eax, 0x1 | ||
mov cr0, eax | ||
|
||
# 跳转到实模式 | ||
ljmp 0x0, entry_last_jump | ||
|
||
.code16 | ||
.global entry_last_jump | ||
entry_last_jump: | ||
# 初始化段寄存器和栈,准备启动 | ||
mov ax, 0x1000 | ||
mov ds, ax | ||
mov es, ax | ||
mov fs, ax | ||
mov gs, ax | ||
mov ss, ax | ||
mov sp, 0xe000 | ||
|
||
# 清理寄存器 | ||
xor eax, eax | ||
xor ebx, ebx | ||
xor ecx, ecx | ||
xor edx, edx | ||
xor ebp, ebp | ||
xor esi, esi | ||
xor edi, edi | ||
|
||
# 跳转到linux内核入口 | ||
ljmp 0x1020, 0 | ||
|
||
# 以下代码不应该被执行,使用一条无效的in指令返回 | ||
in ax, 0x11 | ||
jmp $ | ||
|
||
.global end_of_code | ||
end_of_code: | ||
|
||
# 32位GDT | ||
.balign 16 | ||
.global prot_gdt | ||
prot_gdt: | ||
.quad 0x0000000000000000 # 0x00: null | ||
.quad 0x00cf9b000000ffff # 0x08: code segment (base=0, limit=0xfffff, type=32bit code exec/read, DPL=0, 4k) | ||
.quad 0x00cf93000000ffff # 0x10: data segment (base=0, limit=0xfffff, type=32bit data read/write, DPL=0, 4k) | ||
|
||
.global prot_gdt_desc | ||
prot_gdt_desc: | ||
.short prot_gdt_desc - prot_gdt - 1 # limit | ||
.long prot_gdt # base | ||
|
||
# 16位GDT | ||
.balign 16 | ||
.global prot_16_gdt | ||
prot_16_gdt: | ||
.quad 0x0000000000000000 # 0x00: null | ||
.quad 0x000f9b000000ffff # 0x08: code segment (base=0, limit=0xfffff, type=16bit code exec/read, DPL=0, byte) | ||
.quad 0x000f93000000ffff # 0x10: data segment (base=0, limit=0xfffff, type=16bit data read/write, DPL=0, byte) | ||
|
||
.global prot_16_gdt_desc | ||
prot_16_gdt_desc: | ||
.short prot_16_gdt_desc - prot_16_gdt - 1 # limit | ||
.long prot_16_gdt # base |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
#include "defs.h" | ||
|
||
#pragma pack(push, 1) | ||
typedef struct _kernel_header { | ||
uint8_t _01f0; | ||
uint8_t setup_sects; | ||
uint16_t root_flags; | ||
uint32_t syssize; | ||
uint16_t ramsize; | ||
uint16_t vid_mode; | ||
uint16_t root_dev; | ||
uint16_t boot_flag; | ||
uint16_t jump; | ||
uint32_t header; | ||
uint16_t version; | ||
uint32_t realmode_swtch; | ||
uint16_t start_sys_seg; | ||
uint16_t kernel_version; | ||
uint8_t type_of_loader; | ||
uint8_t loadflags; | ||
uint16_t setup_move_size; | ||
uint32_t code32_start; | ||
uint32_t ramdisk_image; | ||
uint32_t ramdisk_size; | ||
uint32_t bootsect_kludge; | ||
uint16_t heap_end_ptr; | ||
uint8_t ext_loader_ver; | ||
uint8_t ext_loader_type; | ||
uint32_t cmd_line_ptr; | ||
uint32_t initrd_addr_max; | ||
uint32_t kernel_alignment; | ||
uint8_t relocatable_kernel; | ||
uint8_t min_alignment; | ||
uint16_t xloadflags; | ||
uint32_t cmdline_size; | ||
uint32_t hardware_subarch; | ||
uint32_t hardware_subarch_data_l; | ||
uint32_t hardware_subarch_data_h; | ||
uint32_t payload_offset; | ||
uint32_t payload_length; | ||
uint32_t setup_data_l; | ||
uint32_t setup_data_h; | ||
uint32_t pref_address_l; | ||
uint32_t pref_address_h; | ||
uint32_t init_size; | ||
uint32_t handover_offset; | ||
uint32_t kernel_info_offset; | ||
} kernel_header, *kernel_header_ptr; | ||
#pragma pack(pop) | ||
|
||
void cpy4(void *dst, const void *src, uint32_t size) { | ||
const uint32_t * ptr_src = src; | ||
uint32_p ptr_dst = dst; | ||
for (int i = 0; i < size; i += 4) { | ||
*ptr_dst = *ptr_src; | ||
ptr_src++; | ||
ptr_dst++; | ||
} | ||
} | ||
|
||
const char cmd[256] = "console=uart8250,io,0x3f8,115200n8 debug root=/dev/vda\0"; | ||
|
||
int load_kernel(void *kernel_image, void *loc_real, void *stack_end, void *loc_prot) { | ||
kernel_header_ptr orig_header = kernel_image + 0x1f0; | ||
|
||
uint32_t kernel_lower_size = ((orig_header->setup_sects ? orig_header->setup_sects : 4) + 1) * 512; | ||
uint32_t kernel_upper_size = orig_header->syssize * 16; | ||
void *prot = kernel_image + kernel_lower_size; | ||
|
||
cpy4(loc_real, kernel_image, kernel_lower_size); | ||
cpy4(loc_prot, prot, kernel_upper_size); | ||
|
||
void *cmd_base = stack_end; | ||
void *setup_data_base = cmd_base + 256; | ||
|
||
cpy4(cmd_base, cmd, 256); | ||
|
||
kernel_header_ptr header = loc_real + 0x1f0; | ||
|
||
header->vid_mode = 0xffff; | ||
header->type_of_loader = 0xff; | ||
header->loadflags = (header->loadflags & 0x1f) | 0x80; | ||
header->code32_start = (uint32_t)(loc_prot); | ||
header->ramdisk_image = 0; | ||
header->ramdisk_size = 0; | ||
header->heap_end_ptr = (uint16_t)(stack_end - loc_real - 0x200); | ||
header->cmd_line_ptr = (uint32_t)cmd_base; | ||
header->setup_data_l = 0; | ||
header->setup_data_h = 0; | ||
|
||
return 0; | ||
} |
Oops, something went wrong.