Skip to content

Commit

Permalink
x86_64 header
Browse files Browse the repository at this point in the history
  • Loading branch information
BitInit committed Jan 29, 2024
1 parent d0eda16 commit 8fe3b46
Show file tree
Hide file tree
Showing 45 changed files with 708 additions and 64 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ build_dir/
HelloOS
*.s~
*.i
.gdbinit

# Prerequisites
*.d
Expand Down
7 changes: 6 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export CONFIG_x86_64=y
export CC=gcc
export AS=as
export HIDE=@
export DEBUG=
export DEBUG=-g


HelloOS:
Expand All @@ -20,3 +20,8 @@ cleanall:
run:
qemu-system-x86_64 -m 1G -cdrom arch/$(TARGET_ISO) -nographic

debug:
qemu-system-x86_64 -m 1G -cdrom arch/$(TARGET_ISO) -s -S -nographic

kill:
@ps aux | grep [q]emu | awk '{print $$2}' | xargs kill
4 changes: 2 additions & 2 deletions arch/Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
kernel_target=kernel.elf
SRCS = $(BASE_DIR)/init $(BASE_DIR)/kernel $(BASE_DIR)/mm
SRCS = $(BASE_DIR)/init $(BASE_DIR)/kernel $(BASE_DIR)/mm $(BASE_DIR)/lib
ifeq ($(CONFIG_x86_64), y)
SRCS += $(BASE_DIR)/arch/x86
lds = $(BASE_DIR)/arch/x86/boot/vmlinux.lds
Expand All @@ -26,7 +26,7 @@ $(kernel_target): compile

compile:
$(HIDE)for dir in $(SRCS); do \
make -C $$dir || exit 1; \
make -C $$dir compile || exit 1; \
done

clean:
Expand Down
14 changes: 2 additions & 12 deletions arch/x86/Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
export ASFLAGS=--64
export CFLAGS = -I$(BASE_DIR)/include --static -fno-pie -fno-builtin -fno-stack-protector -m64
-include $(BASE_DIR)/scripts/config.mk

x86_srcs = $(wildcard ./boot/*.c) $(wildcard ./kernel/*.c) $(wildcard ./*.c)
x86_objs = $(patsubst %.c, %.o, $(x86_srcs))
Expand All @@ -8,20 +7,11 @@ x86_asm_srcs = $(wildcard ./boot/*.S) $(wildcard ./kernel/*.S)
x86_asm_tmp_srcs = $(patsubst %.S, %.i, $(x86_asm_srcs))
x86_asm_objs = $(patsubst %.S, %.o, $(x86_asm_srcs))

build: $(x86_asm_objs) $(x86_objs)
compile: $(x86_asm_objs) $(x86_objs)

$(x86_objs): $(x86_srcs)
$(x86_asm_objs): $(x86_asm_srcs)

%.o: %.c
@echo "compile $<"
$(CC) $(CFLAGS) $(DEBUG) $< -o $@

%.o: %.S
@echo "compile $<"
$(HIDE)$(CC) -E $(CFLAGS) $< > $<.i
$(HIDE)$(AS) $(ASFLAGS) -o $@ $<.i

clean:
$(HIDE)rm -rf $(x86_objs) $(x86_asm_objs) $(x86_asm_tmp_srcs)

7 changes: 4 additions & 3 deletions arch/x86/boot/header.S
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#define ASM_FILE
#include <asm/multiboot2.h>
#include <os/linkage.h>

.section .text.head
.global startup
Expand All @@ -18,7 +19,7 @@ multiboot_header:

/* required end tag */
.align 8
.short MULTIBOOT_HEADER_TAG_END # type
.short 0 # flags
.long 8 # size
.short MULTIBOOT_HEADER_TAG_END /* type */
.short 0 /* flags */
.long 8 /* size */
multiboot_header_end:
46 changes: 41 additions & 5 deletions arch/x86/boot/vmlinux.lds
Original file line number Diff line number Diff line change
@@ -1,14 +1,50 @@
LOAD_OFFSET = 0xffffffff80000000;
OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")
OUTPUT_ARCH(i386:x86-64)
ENTRY(startup)
SECTIONS
{
. = 0;
.text.head : {
_head = . ;
. = 16M;
.boot : {
*(.text.head)
_ehead = . ;
*(.data.head)
}

. += LOAD_OFFSET;
_text = .;
.text : AT(ADDR(.text) - LOAD_OFFSET) {
*(.text)
*(.text.*)
}
_etext = . ;

.data : AT(ADDR(.data) - LOAD_OFFSET) {
_data = . ;
*(.data)
*(.data.*)
_edata = . ;
}


_rodata = . ;
.rodata : AT(ADDR(.rodata) - LOAD_OFFSET) {
*(.rodata) /* read-only data */
*(.rodata.*)
}
_erodata = . ;

__bss_start = .;
.bss : AT(ADDR(.bss) - LOAD_OFFSET) {
_bss = . ;
*(.bss)
*(.bss.*)
*(COMMON)
. = ALIGN(8);
_end_before_pgt = . ;
. = ALIGN(4096);
pgtable = . ;
. = . + 4096 * 6;
_ebss = .;
}
__bss_stop = .;
_end = .;
}
35 changes: 35 additions & 0 deletions arch/x86/kernel/early_printk.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#include <stdarg.h>

#include <asm/io.h>
#include <asm/page.h>

#include <os/console.h>
#include <os/kernel.h>

#define VGABASE (PAGE_OFFSET + 0xb8000)

void early_vga_write(struct console *con, const char *str, unsigned n) {
unsigned short *dst = (unsigned short*)VGABASE;
for (int i = 0; i < 1000; i++) {
writew((0x7 << 8) | (unsigned short) 'h', dst);
dst++;
}
}

static struct console early_vga_console = {
.name = "earlyvga",
.write = early_vga_write
};

static struct console *early_console = &early_vga_console;

void early_printk(const char *fmt, ...) {
char buf[512];
int n;
va_list ap;

va_start(ap, fmt);
n = vscnprintf(buf, 512, fmt, ap);
early_console->write(early_console, buf, n);
va_end(ap);
}
17 changes: 17 additions & 0 deletions arch/x86/kernel/head64.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#include <asm-generic/sections.h>

#include <os/string.h>
#include <os/start_kernel.h>
#include <os/kernel.h>

void clear_bss() {
// memset(__bss_start, 0,
// (unsigned long) __bss_stop - (unsigned long) __bss_start);
}


void x86_64_start_kernel() {
early_printk("hello world");

start_kernel();
}
171 changes: 170 additions & 1 deletion arch/x86/kernel/head_64.S
Original file line number Diff line number Diff line change
@@ -1,4 +1,173 @@
#include <os/linkage.h>
#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/segment.h>

.code32
.section .text.head
.global startup_64
.extern print
startup_64:
hlt
/* 开启 PAE */
movl %cr4, %eax
btsl $5, %eax
movl %eax, %cr4

/* 设置顶级页目录表 */
movl $(init_level4_pgt - __START_KERNEL_map), %eax
movl %eax, %cr3

/* 开启 long 模式 */
mov $0xC0000080, %ecx
rdmsr
or $(1<<8), %eax
wrmsr

/* 开启分页 */
mov %cr0, %eax
or $(1<<31), %eax
mov %eax, %cr0

movl $head_cpu_gdt_descr, %eax
lgdt 0(%eax)
jmp $__KERNEL_CS, $secondary_startup_64

.code64
secondary_startup_64:
/* 设置初始任务栈 */
movq init_rsp(%rip),%rsp

pushq $0
popfq

/*
* 重新设置 gdt descriptor,
* 因为后续低地址空间是用户空间
*/
lgdt cpu_gdt_descr(%rip)

mov $__KERNEL_DS, %ax
mov %ax, %ds
mov %ax, %ss
mov %ax, %es
mov %ax, %fs
mov %ax, %gs

.extern x86_64_start_kernel
movq $x86_64_start_kernel, %rax
pushq $0
pushq $__KERNEL_CS
pushq %rax
lretq
hlt

ENTRY(init_rsp)
.quad init_thread_union+THREAD_SIZE-8

.text
.code64

.balign PAGE_SIZE
#define NEXT_PAGE(name) \
.balign PAGE_SIZE; \
ENTRY(name)

#define PMDS(START, PERM, COUNT) \
i = 0 ; \
.rept (COUNT) ; \
.quad (START) + (i << 21) + (PERM) ; \
i = i + 1 ; \
.endr

NEXT_PAGE(init_level4_pgt)
.quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
.fill 257,8,0
.quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
.fill 252,8,0
/* (2^48-(2*1024*1024*1024))/(2^39) = 511 */
.quad level3_kernel_pgt - __START_KERNEL_map + _PAGE_TABLE

NEXT_PAGE(level3_ident_pgt)
.quad level2_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
.fill 511,8,0

NEXT_PAGE(level3_kernel_pgt)
.fill 510,8,0
/* (2^48-(2*1024*1024*1024)-((2^39)*511))/(2^30) = 510 */
.quad level2_kernel_pgt - __START_KERNEL_map + _KERNPG_TABLE
.quad level2_fixmap_pgt - __START_KERNEL_map + _PAGE_TABLE

NEXT_PAGE(level2_fixmap_pgt)
.fill 506,8,0
.quad level1_fixmap_pgt - __START_KERNEL_map + _PAGE_TABLE
/* 8MB reserved for vsyscalls + a 2MB hole = 4 + 1 entries */
.fill 5,8,0

NEXT_PAGE(level1_fixmap_pgt)
.fill 512,8,0

NEXT_PAGE(level2_ident_pgt)
/* Since I easily can, map the first 1G.
* Don't set NX because code runs from these pages.
*/
PMDS(0, __PAGE_KERNEL_LARGE_EXEC, PTRS_PER_PMD)

NEXT_PAGE(level2_kernel_pgt)
/*
* 512 MB kernel mapping. We spend a full page on this pagetable
* anyway.
*
* The kernel code+data+bss must not be bigger than that.
*
* (NOTE: at +512MB starts the module area, see MODULES_VADDR.
* If you want to increase this then increase MODULES_VADDR
* too.)
*/
PMDS(0, __PAGE_KERNEL_LARGE_EXEC|_PAGE_GLOBAL, KERNEL_IMAGE_SIZE/PMD_SIZE)

NEXT_PAGE(level2_spare_pgt)
.fill 512,8,0

#undef PMDS
#undef NEXT_PAGE

ENTRY(phys_base)
/* This must match the first entry in level2_kernel_pgt */
.quad 0x0000000000000000

.section .data.head
.align 16
head_cpu_gdt_descr:
.word gdt_end-cpu_gdt_table-1
.quad cpu_gdt_table - __START_KERNEL_map

.data
.align 16
.globl cpu_gdt_descr
cpu_gdt_descr:
.word gdt_end-cpu_gdt_table-1
gdt:
.quad cpu_gdt_table

ENTRY(cpu_gdt_table)
.quad 0x0000000000000000 /* NULL descriptor */
.quad 0x00cf9b000000ffff /* __KERNEL32_CS */
.quad 0x00af9b000000ffff /* __KERNEL_CS */
.quad 0x00cf93000000ffff /* __KERNEL_DS */
.quad 0x00cffb000000ffff /* __USER32_CS */
.quad 0x00cff3000000ffff /* __USER_DS, __USER32_DS */
.quad 0x00affb000000ffff /* __USER_CS */
.quad 0x0 /* unused */
.quad 0,0 /* TSS */
.quad 0,0 /* LDT */
.quad 0,0,0 /* three TLS descriptors */
.quad 0x0000f40000000000 /* node/CPU stored in limit */
gdt_end:

ENTRY(idt_table)
.skip 256 * 16

.section .bss.page_aligned, "aw", @nobits
.align PAGE_SIZE
ENTRY(empty_zero_page)
.skip PAGE_SIZE
8 changes: 8 additions & 0 deletions arch/x86/kernel/init_task.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#include <os/sched.h>
#include <asm/thread_info.h>

union thread_union init_thread_union
__attribute__((__section__(".data.init_task"))) =
{ INIT_THREAD_INFO(init_task) };


Loading

0 comments on commit 8fe3b46

Please sign in to comment.