Skip to content

Commit 8fe3b46

Browse files
committed
x86_64 header
1 parent d0eda16 commit 8fe3b46

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+708
-64
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ build_dir/
1313
HelloOS
1414
*.s~
1515
*.i
16+
.gdbinit
1617

1718
# Prerequisites
1819
*.d

Makefile

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ export CONFIG_x86_64=y
55
export CC=gcc
66
export AS=as
77
export HIDE=@
8-
export DEBUG=
8+
export DEBUG=-g
99

1010

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

23+
debug:
24+
qemu-system-x86_64 -m 1G -cdrom arch/$(TARGET_ISO) -s -S -nographic
25+
26+
kill:
27+
@ps aux | grep [q]emu | awk '{print $$2}' | xargs kill

arch/Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
kernel_target=kernel.elf
2-
SRCS = $(BASE_DIR)/init $(BASE_DIR)/kernel $(BASE_DIR)/mm
2+
SRCS = $(BASE_DIR)/init $(BASE_DIR)/kernel $(BASE_DIR)/mm $(BASE_DIR)/lib
33
ifeq ($(CONFIG_x86_64), y)
44
SRCS += $(BASE_DIR)/arch/x86
55
lds = $(BASE_DIR)/arch/x86/boot/vmlinux.lds
@@ -26,7 +26,7 @@ $(kernel_target): compile
2626

2727
compile:
2828
$(HIDE)for dir in $(SRCS); do \
29-
make -C $$dir || exit 1; \
29+
make -C $$dir compile || exit 1; \
3030
done
3131

3232
clean:

arch/x86/Makefile

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
export ASFLAGS=--64
2-
export CFLAGS = -I$(BASE_DIR)/include --static -fno-pie -fno-builtin -fno-stack-protector -m64
1+
-include $(BASE_DIR)/scripts/config.mk
32

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

11-
build: $(x86_asm_objs) $(x86_objs)
10+
compile: $(x86_asm_objs) $(x86_objs)
1211

1312
$(x86_objs): $(x86_srcs)
1413
$(x86_asm_objs): $(x86_asm_srcs)
1514

16-
%.o: %.c
17-
@echo "compile $<"
18-
$(CC) $(CFLAGS) $(DEBUG) $< -o $@
19-
20-
%.o: %.S
21-
@echo "compile $<"
22-
$(HIDE)$(CC) -E $(CFLAGS) $< > $<.i
23-
$(HIDE)$(AS) $(ASFLAGS) -o $@ $<.i
24-
2515
clean:
2616
$(HIDE)rm -rf $(x86_objs) $(x86_asm_objs) $(x86_asm_tmp_srcs)
2717

arch/x86/boot/header.S

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#define ASM_FILE
22
#include <asm/multiboot2.h>
3+
#include <os/linkage.h>
34

45
.section .text.head
56
.global startup
@@ -18,7 +19,7 @@ multiboot_header:
1819

1920
/* required end tag */
2021
.align 8
21-
.short MULTIBOOT_HEADER_TAG_END # type
22-
.short 0 # flags
23-
.long 8 # size
22+
.short MULTIBOOT_HEADER_TAG_END /* type */
23+
.short 0 /* flags */
24+
.long 8 /* size */
2425
multiboot_header_end:

arch/x86/boot/vmlinux.lds

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,50 @@
1+
LOAD_OFFSET = 0xffffffff80000000;
12
OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")
23
OUTPUT_ARCH(i386:x86-64)
34
ENTRY(startup)
45
SECTIONS
56
{
6-
. = 0;
7-
.text.head : {
8-
_head = . ;
7+
. = 16M;
8+
.boot : {
99
*(.text.head)
10-
_ehead = . ;
10+
*(.data.head)
11+
}
12+
13+
. += LOAD_OFFSET;
14+
_text = .;
15+
.text : AT(ADDR(.text) - LOAD_OFFSET) {
16+
*(.text)
17+
*(.text.*)
18+
}
19+
_etext = . ;
20+
21+
.data : AT(ADDR(.data) - LOAD_OFFSET) {
22+
_data = . ;
23+
*(.data)
24+
*(.data.*)
25+
_edata = . ;
1126
}
1227

13-
28+
_rodata = . ;
29+
.rodata : AT(ADDR(.rodata) - LOAD_OFFSET) {
30+
*(.rodata) /* read-only data */
31+
*(.rodata.*)
32+
}
33+
_erodata = . ;
34+
35+
__bss_start = .;
36+
.bss : AT(ADDR(.bss) - LOAD_OFFSET) {
37+
_bss = . ;
38+
*(.bss)
39+
*(.bss.*)
40+
*(COMMON)
41+
. = ALIGN(8);
42+
_end_before_pgt = . ;
43+
. = ALIGN(4096);
44+
pgtable = . ;
45+
. = . + 4096 * 6;
46+
_ebss = .;
47+
}
48+
__bss_stop = .;
49+
_end = .;
1450
}

arch/x86/kernel/early_printk.c

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#include <stdarg.h>
2+
3+
#include <asm/io.h>
4+
#include <asm/page.h>
5+
6+
#include <os/console.h>
7+
#include <os/kernel.h>
8+
9+
#define VGABASE (PAGE_OFFSET + 0xb8000)
10+
11+
void early_vga_write(struct console *con, const char *str, unsigned n) {
12+
unsigned short *dst = (unsigned short*)VGABASE;
13+
for (int i = 0; i < 1000; i++) {
14+
writew((0x7 << 8) | (unsigned short) 'h', dst);
15+
dst++;
16+
}
17+
}
18+
19+
static struct console early_vga_console = {
20+
.name = "earlyvga",
21+
.write = early_vga_write
22+
};
23+
24+
static struct console *early_console = &early_vga_console;
25+
26+
void early_printk(const char *fmt, ...) {
27+
char buf[512];
28+
int n;
29+
va_list ap;
30+
31+
va_start(ap, fmt);
32+
n = vscnprintf(buf, 512, fmt, ap);
33+
early_console->write(early_console, buf, n);
34+
va_end(ap);
35+
}

arch/x86/kernel/head64.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#include <asm-generic/sections.h>
2+
3+
#include <os/string.h>
4+
#include <os/start_kernel.h>
5+
#include <os/kernel.h>
6+
7+
void clear_bss() {
8+
// memset(__bss_start, 0,
9+
// (unsigned long) __bss_stop - (unsigned long) __bss_start);
10+
}
11+
12+
13+
void x86_64_start_kernel() {
14+
early_printk("hello world");
15+
16+
start_kernel();
17+
}

arch/x86/kernel/head_64.S

Lines changed: 170 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,173 @@
1+
#include <os/linkage.h>
2+
#include <asm/page.h>
3+
#include <asm/pgtable.h>
4+
#include <asm/segment.h>
5+
16
.code32
7+
.section .text.head
28
.global startup_64
9+
.extern print
310
startup_64:
4-
hlt
11+
/* 开启 PAE */
12+
movl %cr4, %eax
13+
btsl $5, %eax
14+
movl %eax, %cr4
15+
16+
/* 设置顶级页目录表 */
17+
movl $(init_level4_pgt - __START_KERNEL_map), %eax
18+
movl %eax, %cr3
19+
20+
/* 开启 long 模式 */
21+
mov $0xC0000080, %ecx
22+
rdmsr
23+
or $(1<<8), %eax
24+
wrmsr
25+
26+
/* 开启分页 */
27+
mov %cr0, %eax
28+
or $(1<<31), %eax
29+
mov %eax, %cr0
30+
31+
movl $head_cpu_gdt_descr, %eax
32+
lgdt 0(%eax)
33+
jmp $__KERNEL_CS, $secondary_startup_64
34+
35+
.code64
36+
secondary_startup_64:
37+
/* 设置初始任务栈 */
38+
movq init_rsp(%rip),%rsp
39+
40+
pushq $0
41+
popfq
42+
43+
/*
44+
* 重新设置 gdt descriptor,
45+
* 因为后续低地址空间是用户空间
46+
*/
47+
lgdt cpu_gdt_descr(%rip)
48+
49+
mov $__KERNEL_DS, %ax
50+
mov %ax, %ds
51+
mov %ax, %ss
52+
mov %ax, %es
53+
mov %ax, %fs
54+
mov %ax, %gs
55+
56+
.extern x86_64_start_kernel
57+
movq $x86_64_start_kernel, %rax
58+
pushq $0
59+
pushq $__KERNEL_CS
60+
pushq %rax
61+
lretq
62+
hlt
63+
64+
ENTRY(init_rsp)
65+
.quad init_thread_union+THREAD_SIZE-8
66+
67+
.text
68+
.code64
69+
70+
.balign PAGE_SIZE
71+
#define NEXT_PAGE(name) \
72+
.balign PAGE_SIZE; \
73+
ENTRY(name)
74+
75+
#define PMDS(START, PERM, COUNT) \
76+
i = 0 ; \
77+
.rept (COUNT) ; \
78+
.quad (START) + (i << 21) + (PERM) ; \
79+
i = i + 1 ; \
80+
.endr
81+
82+
NEXT_PAGE(init_level4_pgt)
83+
.quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
84+
.fill 257,8,0
85+
.quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
86+
.fill 252,8,0
87+
/* (2^48-(2*1024*1024*1024))/(2^39) = 511 */
88+
.quad level3_kernel_pgt - __START_KERNEL_map + _PAGE_TABLE
89+
90+
NEXT_PAGE(level3_ident_pgt)
91+
.quad level2_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
92+
.fill 511,8,0
93+
94+
NEXT_PAGE(level3_kernel_pgt)
95+
.fill 510,8,0
96+
/* (2^48-(2*1024*1024*1024)-((2^39)*511))/(2^30) = 510 */
97+
.quad level2_kernel_pgt - __START_KERNEL_map + _KERNPG_TABLE
98+
.quad level2_fixmap_pgt - __START_KERNEL_map + _PAGE_TABLE
99+
100+
NEXT_PAGE(level2_fixmap_pgt)
101+
.fill 506,8,0
102+
.quad level1_fixmap_pgt - __START_KERNEL_map + _PAGE_TABLE
103+
/* 8MB reserved for vsyscalls + a 2MB hole = 4 + 1 entries */
104+
.fill 5,8,0
105+
106+
NEXT_PAGE(level1_fixmap_pgt)
107+
.fill 512,8,0
108+
109+
NEXT_PAGE(level2_ident_pgt)
110+
/* Since I easily can, map the first 1G.
111+
* Don't set NX because code runs from these pages.
112+
*/
113+
PMDS(0, __PAGE_KERNEL_LARGE_EXEC, PTRS_PER_PMD)
114+
115+
NEXT_PAGE(level2_kernel_pgt)
116+
/*
117+
* 512 MB kernel mapping. We spend a full page on this pagetable
118+
* anyway.
119+
*
120+
* The kernel code+data+bss must not be bigger than that.
121+
*
122+
* (NOTE: at +512MB starts the module area, see MODULES_VADDR.
123+
* If you want to increase this then increase MODULES_VADDR
124+
* too.)
125+
*/
126+
PMDS(0, __PAGE_KERNEL_LARGE_EXEC|_PAGE_GLOBAL, KERNEL_IMAGE_SIZE/PMD_SIZE)
127+
128+
NEXT_PAGE(level2_spare_pgt)
129+
.fill 512,8,0
130+
131+
#undef PMDS
132+
#undef NEXT_PAGE
133+
134+
ENTRY(phys_base)
135+
/* This must match the first entry in level2_kernel_pgt */
136+
.quad 0x0000000000000000
137+
138+
.section .data.head
139+
.align 16
140+
head_cpu_gdt_descr:
141+
.word gdt_end-cpu_gdt_table-1
142+
.quad cpu_gdt_table - __START_KERNEL_map
143+
144+
.data
145+
.align 16
146+
.globl cpu_gdt_descr
147+
cpu_gdt_descr:
148+
.word gdt_end-cpu_gdt_table-1
149+
gdt:
150+
.quad cpu_gdt_table
151+
152+
ENTRY(cpu_gdt_table)
153+
.quad 0x0000000000000000 /* NULL descriptor */
154+
.quad 0x00cf9b000000ffff /* __KERNEL32_CS */
155+
.quad 0x00af9b000000ffff /* __KERNEL_CS */
156+
.quad 0x00cf93000000ffff /* __KERNEL_DS */
157+
.quad 0x00cffb000000ffff /* __USER32_CS */
158+
.quad 0x00cff3000000ffff /* __USER_DS, __USER32_DS */
159+
.quad 0x00affb000000ffff /* __USER_CS */
160+
.quad 0x0 /* unused */
161+
.quad 0,0 /* TSS */
162+
.quad 0,0 /* LDT */
163+
.quad 0,0,0 /* three TLS descriptors */
164+
.quad 0x0000f40000000000 /* node/CPU stored in limit */
165+
gdt_end:
166+
167+
ENTRY(idt_table)
168+
.skip 256 * 16
169+
170+
.section .bss.page_aligned, "aw", @nobits
171+
.align PAGE_SIZE
172+
ENTRY(empty_zero_page)
173+
.skip PAGE_SIZE

arch/x86/kernel/init_task.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#include <os/sched.h>
2+
#include <asm/thread_info.h>
3+
4+
union thread_union init_thread_union
5+
__attribute__((__section__(".data.init_task"))) =
6+
{ INIT_THREAD_INFO(init_task) };
7+
8+

0 commit comments

Comments
 (0)