将内核层空间移动到0xffff800000000000

This commit is contained in:
fslongjin 2022-04-09 21:11:07 +08:00
parent 24b351c9ec
commit 05dc7ac73b
14 changed files with 321 additions and 175 deletions

View File

@ -6,7 +6,7 @@ all:
@list='$(SUBDIRS)'; for subdir in $$list; do \
echo "make all in $$subdir";\
cd $$subdir;\
make all;\
$(MAKE) all;\
cd ..;\
done
@ -14,7 +14,7 @@ all:
clean:
@list='$(SUBDIRS)'; for subdir in $$list; do \
echo "Clean in dir: $$subdir";\
cd $$subdir && make clean;\
cd $$subdir && $(MAKE) clean;\
cd .. ;\
done

View File

@ -11,7 +11,7 @@ CFLAGS := -mcmodel=large -fno-builtin -m64 -g -O0 -I .
ARCH=x86_64
# 控制操作系统使用的中断控制器 _INTR_8259A_ _INTR_APIC_
PIC := _INTR_APIC_
CFLAGS += -D $(PIC) -D $(ARCH)
CFLAGS += -D $(PIC) -D $(ARCH)
ASFLAGS := --64
@ -56,6 +56,10 @@ slab.o: mm/slab.c
process.o: process/process.c
gcc $(CFLAGS) -c process/process.c -o process/process.o
sched.o: sched/sched.c
gcc $(CFLAGS) -c sched/sched.c -o sched/sched.o
syscall.o: syscall/syscall.c
gcc $(CFLAGS) -c syscall/syscall.c -o syscall/syscall.o
@ -127,9 +131,9 @@ all: kernel
objcopy -I elf64-x86-64 -O elf64-x86-64 -R ".comment" -R ".eh_frame" kernel ../bin/kernel/kernel.elf
#
kernel: head.o entry.o main.o printk.o trap.o mm.o slab.o irq.o pic.o process.o syscall.o multiboot2.o cpu.o acpi.o ps2_keyboard.o ps2_mouse.o ata.o pci.o ahci.o smp.o apu_boot.o rtc.o HPET.o softirq.o timer.o $(OBJ_LIST)
kernel: head.o entry.o main.o printk.o trap.o mm.o slab.o irq.o pic.o process.o sched.o syscall.o multiboot2.o cpu.o acpi.o ps2_keyboard.o ps2_mouse.o ata.o pci.o ahci.o smp.o apu_boot.o rtc.o HPET.o softirq.o timer.o $(OBJ_LIST)
ld -b elf64-x86-64 -z muldefs -o kernel head.o exception/entry.o main.o common/printk.o exception/trap.o exception/irq.o mm/mm.o mm/slab.o process/process.o syscall/syscall.o driver/multiboot2/multiboot2.o \
common/cpu.o smp/smp.o smp/apu_boot.o exception/softirq.o \
common/cpu.o smp/smp.o smp/apu_boot.o exception/softirq.o sched/sched.o \
driver/acpi/acpi.o driver/interrupt/pic.o driver/keyboard/ps2_keyboard.o driver/mouse/ps2_mouse.o driver/disk/ata.o driver/pci/pci.o driver/disk/ahci/ahci.o driver/timers/rtc/rtc.o driver/timers/HPET/HPET.o driver/timers/timer.o \
$(LD_LIST) \
-T link.lds

View File

@ -7,7 +7,7 @@ void cpu_init(void)
// 获取处理器制造商信息
uint tmp_info[4] = {0};
cpu_cpuid(0, 0, &tmp_info[0], &tmp_info[1], &tmp_info[2], &tmp_info[3]);
// 保存CPU支持的最大cpuid指令主功能号
Cpu_cpuid_max_Basic_mop = tmp_info[0];
// 保存制造商名称
@ -37,28 +37,28 @@ void cpu_init(void)
// EAX中包含 Version Informatin Type,Family,Model,and Stepping ID
Cpu_Stepping_ID = tmp_info[0] & 0xf;
Cpu_Model_ID = (tmp_info[0]>>4) & 0xf;
Cpu_Family_ID = (tmp_info[0]>>8) & 0xf;
Cpu_Processor_Type = (tmp_info[0]>>12)& 0x3;
Cpu_Model_ID = (tmp_info[0] >> 4) & 0xf;
Cpu_Family_ID = (tmp_info[0] >> 8) & 0xf;
Cpu_Processor_Type = (tmp_info[0] >> 12) & 0x3;
// 14-15位保留
Cpu_Extended_Model_ID = (tmp_info[0]>>16)&0xf;
Cpu_Extended_Family_ID = (tmp_info[0]>>20)&0xff;
//31-25位保留
kinfo("Family ID=%#03lx\t Extended Family ID=%#03lx\t Processor Type=%#03lx\t",Cpu_Family_ID, Cpu_Extended_Family_ID, Cpu_Processor_Type);
kinfo("Model ID=%#03lx\t Extended Model ID=%#03lx\tStepping ID=%#03lx\t",Cpu_Model_ID, Cpu_Extended_Model_ID,Cpu_Stepping_ID);
Cpu_Extended_Model_ID = (tmp_info[0] >> 16) & 0xf;
Cpu_Extended_Family_ID = (tmp_info[0] >> 20) & 0xff;
// 31-25位保留
kinfo("Family ID=%#03lx\t Extended Family ID=%#03lx\t Processor Type=%#03lx\t", Cpu_Family_ID, Cpu_Extended_Family_ID, Cpu_Processor_Type);
kinfo("Model ID=%#03lx\t Extended Model ID=%#03lx\tStepping ID=%#03lx\t", Cpu_Model_ID, Cpu_Extended_Model_ID, Cpu_Stepping_ID);
// 使用0x80000008主功能号查询处理器支持的最大可寻址地址线宽度
cpu_cpuid(0x80000008, 0, &tmp_info[0], &tmp_info[1], &tmp_info[2], &tmp_info[3]);
Cpu_max_phys_addrline_size = tmp_info[0]&0xff;
Cpu_max_linear_addrline_size = (tmp_info[0]>>8)&0xff;
Cpu_max_phys_addrline_size = tmp_info[0] & 0xff;
Cpu_max_linear_addrline_size = (tmp_info[0] >> 8) & 0xff;
kinfo("Cpu_max_phys_addrline_size = %d", Cpu_max_phys_addrline_size);
kinfo("Cpu_max_linear_addrline_size = %d", Cpu_max_linear_addrline_size);
cpu_cpuid(0x80000000, 0, &tmp_info[0], &tmp_info[1], &tmp_info[2], &tmp_info[3]);
Cpu_cpuid_max_Extended_mop = tmp_info[0];
kinfo("Max basic mop=%#05lx",Cpu_cpuid_max_Basic_mop);
kinfo("Max extended mop=%#05lx",Cpu_cpuid_max_Extended_mop);
kinfo("Max basic mop=%#05lx", Cpu_cpuid_max_Basic_mop);
kinfo("Max extended mop=%#05lx", Cpu_cpuid_max_Extended_mop);
return;
}

View File

@ -28,16 +28,19 @@ int printk_init(const int char_size_x, const int char_size_y)
struct multiboot_tag_framebuffer_info_t info;
int reserved;
multiboot2_iter(multiboot2_get_Framebuffer_info, &info, &reserved);
pos.width = info.framebuffer_width;
pos.height = info.framebuffer_height;
pos.char_size_x = char_size_x;
pos.char_size_y = char_size_y;
pos.max_x = calculate_max_charNum(pos.width, char_size_x);
pos.max_y = calculate_max_charNum(pos.height, char_size_y);
VBE_FB_phys_addr = (ul)info.framebuffer_addr;
pos.FB_address = (uint *)0x0000000003000000;
pos.FB_address = (uint *)0xffff800003000000;
pos.FB_length = 1UL * pos.width * pos.height;
// 初始化自旋锁
@ -69,11 +72,11 @@ int printk_init(const int char_size_x, const int char_size_y)
pos.x = 0;
pos.y = 0;
cls();
kdebug("width=%d\theight=%d", pos.width, pos.height);
return 0;
}
@ -532,7 +535,6 @@ static char *write_float_point_num(char *str, double num, int field_width, int p
// 设置填充元素
pad = (flags & PAD_ZERO) ? '0' : ' ';
sign = 0;
if (flags & SIGN && num < 0)
{

View File

@ -7,6 +7,7 @@ struct pci_device_structure_header_t *ahci_devs[MAX_AHCI_DEVICES];
uint32_t count_ahci_devices = 0;
uint64_t ahci_port_base_vaddr; // 端口映射base addr
uint64_t ahci_port_base_phys_addr; // 端口映射的物理基地址ahci控制器的参数的地址都是物理地址
static void start_cmd(HBA_PORT *port);
static void stop_cmd(HBA_PORT *port);
@ -24,21 +25,24 @@ static int ahci_find_cmdslot(HBA_PORT *port);
*/
void ahci_init()
{
kinfo("Initializing AHCI...");
pci_get_device_structure(0x1, 0x6, ahci_devs, &count_ahci_devices);
// 映射ABAR
mm_map_phys_addr(AHCI_MAPPING_BASE, ((ul)(((struct pci_device_structure_general_device_t *)(ahci_devs[0]))->BAR5)) & PAGE_2M_MASK, PAGE_2M_SIZE, PAGE_KERNEL_PAGE | PAGE_PWT | PAGE_PCD);
//kdebug("ABAR mapped!");
// kdebug("ABAR mapped!");
for (int i = 0; i < count_ahci_devices; ++i)
{
//kdebug("[%d] class_code=%d, sub_class=%d, progIF=%d, ABAR=%#010lx", i, ahci_devs[i]->Class_code, ahci_devs[i]->SubClass, ahci_devs[i]->ProgIF, ((struct pci_device_structure_general_device_t *)(ahci_devs[i]))->BAR5);
// 赋值HBA_MEM结构体
// kdebug("[%d] class_code=%d, sub_class=%d, progIF=%d, ABAR=%#010lx", i, ahci_devs[i]->Class_code, ahci_devs[i]->SubClass, ahci_devs[i]->ProgIF, ((struct pci_device_structure_general_device_t *)(ahci_devs[i]))->BAR5);
// 赋值HBA_MEM结构体
ahci_devices[i].dev_struct = ahci_devs[i];
ahci_devices[i].hba_mem = (HBA_MEM *)(cal_HBA_MEM_VIRT_ADDR(i));
kdebug("ahci_devices[i].hba_mem = %#018lx", (ul)ahci_devices[i].hba_mem);
}
// todo: 支持多个ahci控制器。
ahci_port_base_vaddr = (uint64_t)kmalloc(1048576, 0);
kdebug("ahci_port_base_vaddr=%#018lx", ahci_port_base_vaddr);
ahci_probe_port(0);
port_rebase(&ahci_devices[0].hba_mem->ports[0], 0);
@ -118,7 +122,7 @@ static void ahci_probe_port(const uint32_t device_num)
static void start_cmd(HBA_PORT *port)
{
// Wait until CR (bit15) is cleared
while (port->cmd & HBA_PxCMD_CR)
while ((port->cmd) & HBA_PxCMD_CR)
;
// Set FRE (bit4) and ST (bit0)
@ -160,29 +164,29 @@ static void port_rebase(HBA_PORT *port, int portno)
// Command list entry maxim count = 32
// Command list maxim size = 32*32 = 1K per port
port->clb = ahci_port_base_vaddr + (portno << 10);
port->clb = virt_2_phys(ahci_port_base_vaddr + (portno << 10));
memset((void *)(port->clb), 0, 1024);
memset((void *)(phys_2_virt(port->clb)), 0, 1024);
// FIS offset: 32K+256*portno
// FIS entry size = 256 bytes per port
port->fb = ahci_port_base_vaddr + (32 << 10) + (portno << 8);
port->fb = virt_2_phys(ahci_port_base_vaddr + (32 << 10) + (portno << 8));
memset((void *)(port->fb), 0, 256);
memset((void *)(phys_2_virt(port->fb)), 0, 256);
// Command table offset: 40K + 8K*portno
// Command table size = 256*32 = 8K per port
HBA_CMD_HEADER *cmdheader = (HBA_CMD_HEADER *)(port->clb);
HBA_CMD_HEADER *cmdheader = (HBA_CMD_HEADER *)(phys_2_virt(port->clb));
for (int i = 0; i < 32; ++i)
{
cmdheader[i].prdtl = 8; // 8 prdt entries per command table
// 256 bytes per command table, 64+16+48+16*8
// Command table offset: 40K + 8K*portno + cmdheader_index*256
cmdheader[i].ctba = ahci_port_base_vaddr + (40 << 10) + (portno << 13) + (i << 8);
cmdheader[i].ctba = virt_2_phys((ahci_port_base_vaddr + (40 << 10) + (portno << 13) + (i << 8)));
memset((void *)cmdheader[i].ctba, 0, 256);
memset((void *)phys_2_virt(cmdheader[i].ctba), 0, 256);
}
start_cmd(port); // Start command engine
}
@ -206,20 +210,20 @@ static bool ahci_read(HBA_PORT *port, uint32_t startl, uint32_t starth, uint32_t
if (slot == -1)
return E_NOEMPTYSLOT;
HBA_CMD_HEADER *cmdheader = (HBA_CMD_HEADER *)port->clb;
HBA_CMD_HEADER *cmdheader = (HBA_CMD_HEADER *)phys_2_virt(port->clb);
cmdheader += slot;
cmdheader->cfl = sizeof(FIS_REG_H2D) / sizeof(uint32_t); // Command FIS size
cmdheader->w = 0; // Read from device
cmdheader->prdtl = (uint16_t)((count - 1) >> 4) + 1; // PRDT entries count
HBA_CMD_TBL *cmdtbl = (HBA_CMD_TBL *)(cmdheader->ctba);
HBA_CMD_TBL *cmdtbl = (HBA_CMD_TBL *)phys_2_virt(cmdheader->ctba);
memset(cmdtbl, 0, sizeof(HBA_CMD_TBL) + (cmdheader->prdtl - 1) * sizeof(HBA_PRDT_ENTRY));
// 8K bytes (16 sectors) per PRDT
int i;
for (i = 0; i < cmdheader->prdtl - 1; ++i)
{
cmdtbl->prdt_entry[i].dba = buf;
cmdtbl->prdt_entry[i].dba = virt_2_phys(buf);
cmdtbl->prdt_entry[i].dbc = 8 * 1024 - 1; // 8K bytes (this value should always be set to 1 less than the actual value)
cmdtbl->prdt_entry[i].i = 1;
buf += 4 * 1024; // 4K uint16_ts
@ -227,7 +231,7 @@ static bool ahci_read(HBA_PORT *port, uint32_t startl, uint32_t starth, uint32_t
}
// Last entry
cmdtbl->prdt_entry[i].dba = buf;
cmdtbl->prdt_entry[i].dba = virt_2_phys(buf);
cmdtbl->prdt_entry[i].dbc = (count << 9) - 1; // 512 bytes per sector
cmdtbl->prdt_entry[i].i = 1;
@ -296,7 +300,7 @@ static bool ahci_write(HBA_PORT *port, uint32_t startl, uint32_t starth, uint32_
if (slot == -1)
return E_NOEMPTYSLOT;
HBA_CMD_HEADER *cmdheader = (HBA_CMD_HEADER *)port->clb;
HBA_CMD_HEADER *cmdheader = (HBA_CMD_HEADER *)phys_2_virt(port->clb);
cmdheader += slot;
cmdheader->cfl = sizeof(FIS_REG_H2D) / sizeof(uint32_t); // Command FIS size
@ -305,7 +309,7 @@ static bool ahci_write(HBA_PORT *port, uint32_t startl, uint32_t starth, uint32_
cmdheader->p = 1;
cmdheader->prdtl = (uint16_t)((count - 1) >> 4) + 1; // PRDT entries count
HBA_CMD_TBL *cmdtbl = (HBA_CMD_TBL *)(cmdheader->ctba);
HBA_CMD_TBL *cmdtbl = (HBA_CMD_TBL *)phys_2_virt(cmdheader->ctba);
memset(cmdtbl, 0, sizeof(HBA_CMD_TBL) + (cmdheader->prdtl - 1) * sizeof(HBA_PRDT_ENTRY));
int i = 0;
@ -438,7 +442,7 @@ static void ahci_end_request()
ahci_req_queue.in_service = NULL;
// 进行下一轮的磁盘请求 由于未实现单独的io调度器这里会造成长时间的io等待
if (ahci_req_queue.request_count>0)
if (ahci_req_queue.request_count > 0)
ahci_query_disk();
}

View File

@ -7,6 +7,8 @@
#include "../../acpi/acpi.h"
#include <exception/softirq.h>
#include <process/process.h>
#include <sched/sched.h>
// 导出定义在irq.c中的中段门表
extern void (*interrupt_table[24])(void);
@ -472,6 +474,11 @@ void do_IRQ(struct pt_regs *rsp, ul number)
// 检测是否有未处理的软中断
if (softirq_status != 0)
do_softirq();
// 检测当前进程是否可被调度
struct process_control_block *current_proc = get_current_pcb();
if (current_proc->flags & PROC_NEED_SCHED)
sched_cfs();
}
/**

View File

@ -3,18 +3,18 @@
#include "../../common/glib.h"
#include "../../common/kprint.h"
uintptr_t boot_info_addr;
uintptr_t multiboot2_boot_info_addr;
unsigned int multiboot2_magic;
unsigned int boot_info_size;
unsigned int multiboot2_boot_info_size;
bool multiboot2_init(void)
{
uintptr_t *addr = (uintptr_t *)boot_info_addr;
uintptr_t *addr = (uintptr_t *)multiboot2_boot_info_addr;
if (multiboot2_magic != MULTIBOOT2_BOOTLOADER_MAGIC)
;
return false;
// addr+0 处保存了大小
boot_info_size = *(unsigned int *)addr;
multiboot2_boot_info_size = *(unsigned int *)addr;
return true;
}
@ -22,9 +22,9 @@ void multiboot2_iter(bool (*_fun)(const struct iter_data_t *, void *, unsigned i
void *data, unsigned int *count)
{
uintptr_t addr = boot_info_addr;
// 下一字节开始为 tag 信息
struct iter_data_t *tag = (struct iter_data_t *)(addr + 8);
uintptr_t addr = multiboot2_boot_info_addr;
// 接下来的第8字节开始为 tag 信息
struct iter_data_t *tag = (struct iter_data_t *)((void*)addr + 8);
for (; tag->type != MULTIBOOT_TAG_TYPE_END;
tag = (struct iter_data_t *)((uint8_t *)tag + ALIGN(tag->size, 8)))
{

View File

@ -27,6 +27,7 @@
*/
extern unsigned int multiboot2_magic;
extern uintptr_t multiboot2_boot_info_addr;
/* How many bytes from the start of the file we search for the header. */
static const unsigned int MULTIBOOT_SEARCH = 32768;

View File

@ -4,6 +4,8 @@
#include <driver/interrupt/apic/apic.h>
#include <exception/softirq.h>
#include <driver/timers/timer.h>
#include <process/process.h>
#include <sched/sched.h>
static struct acpi_HPET_description_table_t *hpet_table;
static uint64_t HPET_REG_BASE = 0;
@ -52,8 +54,27 @@ void HPET_handler(uint64_t number, uint64_t param, struct pt_regs *regs)
{
case 0: // 定时器0中断
++timer_jiffies;
if (container_of(list_next(&timer_func_head.list), struct timer_func_list_t, list)->expire_jiffies <= timer_jiffies) // 若当前时间比定时任务的时间间隔大,则进入中断下半部
// 若当前时间比定时任务的时间间隔大,则进入中断下半部
if (container_of(list_next(&timer_func_head.list), struct timer_func_list_t, list)->expire_jiffies <= timer_jiffies)
set_softirq_status(TIMER_SIRQ);
/*
switch (current_pcb->priority)
{
case 0:
case 1:
--sched_cfs_ready_queue.cpu_exec_proc_jiffies;
++current_pcb->virtual_runtime;
break;
case 2:
default:
sched_cfs_ready_queue.cpu_exec_proc_jiffies -= 2;
current_pcb->virtual_runtime += 2;
break;
}
if (sched_cfs_ready_queue.cpu_exec_proc_jiffies <= 0)
current_pcb->flags |= PROC_NEED_SCHED;
*/
break;
default:
@ -75,15 +96,16 @@ int HPET_init()
hpet_table = (struct acpi_HPET_description_table_t *)hpet_table_addr;
// 由于这段内存与io/apic的映射在同一物理页内因此不需要重复映射
HPET_REG_BASE = SPECIAL_MEMOEY_MAPPING_VIRT_ADDR_BASE + hpet_table->address;
// 读取计时精度并计算频率
uint64_t tmp;
tmp = *(uint64_t *)(HPET_REG_BASE + GCAP_ID);
HPET_COUNTER_CLK_PERIOD = (tmp >> 32) & 0xffffffff;
HPET_freq = 1.0 * 1e15 / HPET_COUNTER_CLK_PERIOD;
HPET_NUM_TIM_CAP = (tmp >> 8) & 0x1f; // 读取计时器数量
kinfo("HPET CLK_PERIOD=%#03lx Frequency=%f", HPET_COUNTER_CLK_PERIOD, HPET_freq);
double x = 1*2;
x = 1.0*3.65;
//kinfo("HPET CLK_PERIOD=%#03lx Frequency=%f", HPET_COUNTER_CLK_PERIOD, (double)HPET_freq);
struct apic_IO_APIC_RTE_entry entry;
// 使用I/O APIC 的IRQ2接收hpet定时器0的中断
apic_make_rte_entry(&entry, 34, IO_APIC_FIXED, DEST_PHYSICAL, IDLE, POLARITY_HIGH, IRR_RESET, EDGE_TRIGGER, MASKED, 0);

View File

@ -158,9 +158,10 @@
//
.SET CHECKSUM, -(MULTIBOOT2_HEADER_MAGIC + MULTIBOOT_ARCHITECTURE_I386 + HEADER_LENGTH)
// 8
.section .multiboot_header
.align MULTIBOOT_HEADER_ALIGN
//
.section .multiboot_header
multiboot_header:
//
.long MULTIBOOT2_HEADER_MAGIC
@ -189,79 +190,25 @@ framebuffer_tag_end:
.long 8
multiboot_header_end:
.section .bootstrap
// 4KB/
.section .data
.align 0x1000
.global pml4
pml4:
.skip 0x1000
pdpt:
.skip 0x1000
pd:
.skip 0x1000
pt:
.skip 0x1000
// GDT
.align 16
gdt64:
null_desc:
.short 0xFFFF
.short 0
.byte 0
.byte 0
.byte 0
.byte 0
code_desc:
.short 0
.short 0
.byte 0
.byte 0x9A
.byte 0x20
.byte 0
data_desc:
.short 0
.short 0
.byte 0
.byte 0x92
.byte 0
.byte 0
user_code_desc:
.short 0
.short 0
.byte 0
.byte 0xFA
.byte 0x20
.byte 0
user_data_desc:
.short 0
.short 0
.byte 0
.byte 0xF2
.byte 0
.byte 0
gdt64_pointer:
.short gdt64_pointer-gdt64-1
.quad gdt64
gdt64_pointer64:
.short gdt64_pointer-gdt64-1
.quad gdt64
.section .text
.global _start
.type _start, @function
# multiboot2.cpp
.extern _start64
.extern boot_info_addr
.extern multiboot2_magic
.extern _start64
_start:
ENTRY(_start)
//
cli
// multiboot2_info
mov %ebx, boot_info_addr
mov %ebx, mb2_info
//mov %ebx, %e8
//
mov %eax, multiboot2_magic
mov %eax, mb2_magic
//mov %eax, %e9
/
// 1. PAE
mov %cr4, %eax
@ -318,13 +265,22 @@ enter_head_from_ap_boot:
mov $gdt64_pointer, %eax
lgdt 0(%eax)
// 6. 64
jmp $0x8, $_start64
jmp $0x8, $ready_to_start_64
hlt
ret
.code64
ready_to_start_64:
//6. start64
movq switch_to_start64(%rip), %rax
pushq $0x08 //
pushq %rax
lretq
switch_to_start64:
.quad _start64
.section .text
.code64
.global _start64
@ -367,6 +323,7 @@ ENTRY(_start64)
mov $__PDPTE, %ebx
or $0x3, %ebx
mov %ebx, 0(%eax)
mov %ebx, 256(%eax)
//
mov $__PDPTE, %eax
@ -402,6 +359,7 @@ entry64:
movq %rax, %ss
movq _stack_start(%rip), %rsp //rsp
// apu
movq $0x1b, %rcx // IA32_APIC_BASE.BSP[8]apu
@ -482,7 +440,15 @@ SetUp_TSS64:
or $(3 << 9), %ax //set CR4.OSFXSR and CR4.OSXMMEXCPT at the same time
movq %rax, %cr4
call Start_Kernel
//call Start_Kernel
movq go_to_kernel(%rip), %rax /* movq address */
pushq $0x08
pushq %rax
movq mb2_info, %r15
movq mb2_magic, %r14
lretq
go_to_kernel:
.quad Start_Kernel
@ -517,7 +483,6 @@ ENTRY(_stack_start)
//
.align 0x1000 //4k
.org 0x1000 //0x1000
@ -586,8 +551,9 @@ __PDE:
.quad 0xe1e00083
.fill 468,8,0
// GDT
.section .data
.align 16
.global GDT_Table // 使GDT访
@ -627,3 +593,66 @@ IDT_BASE: .quad IDT_Table
TSS64_Table:
.fill 13, 8, 0
TSS64_END:
.section .bootstrap.data
mb2_magic: .quad 0
mb2_info: .quad 0
.code32
// 4KB/
.align 0x1000
.global pml4
pml4:
.skip 0x1000
pdpt:
.skip 0x1000
pd:
.skip 0x1000
pt:
.skip 0x1000
// GDT
.align 16
gdt64:
null_desc:
.short 0xFFFF
.short 0
.byte 0
.byte 0
.byte 0
.byte 0
code_desc:
.short 0
.short 0
.byte 0
.byte 0x9A
.byte 0x20
.byte 0
data_desc:
.short 0
.short 0
.byte 0
.byte 0x92
.byte 0
.byte 0
user_code_desc:
.short 0
.short 0
.byte 0
.byte 0xFA
.byte 0x20
.byte 0
user_data_desc:
.short 0
.short 0
.byte 0
.byte 0xF2
.byte 0
.byte 0
gdt64_pointer:
.short gdt64_pointer-gdt64-1
.quad gdt64
gdt64_pointer64:
.short gdt64_pointer-gdt64-1
.quad gdt64

View File

@ -5,27 +5,37 @@ ENTRY(_start)
SECTIONS
{
KERNEL_VMA = 0xffff800000000000;
//KERNEL_VMA = 0;
. = 0;
. = 0x100000;
.text :
.boot.text :
{
KEEP(*(.multiboot_header))
head.o(.bootstrap)
head.o(.bootstrap.code64)
head.o(.bootstrap.data)
. = ALIGN(4096);
}
. += KERNEL_VMA;
.text : AT(ADDR(.text) - KERNEL_VMA)
{
_text = .;
*(.multiboot_header)
*(.text)
_etext = .;
}
. = ALIGN(8);
.data :
.data : AT(ADDR(.data) - KERNEL_VMA)
{
_data = .;
*(.data)
_edata = .;
}
.rodata :
.rodata : AT(ADDR(.rodata) - KERNEL_VMA)
{
_rodata = .;
*(.rodata)
@ -33,14 +43,14 @@ SECTIONS
}
. = ALIGN(32768);
.data.init_proc_union : { *(.data.init_proc_union) }
.bss :
.data.init_proc_union : AT(ADDR(.data.init_proc_union) - KERNEL_VMA)
{ *(.data.init_proc_union) }
.bss : AT(ADDR(.bss) - KERNEL_VMA)
{
_bss = .;
*(.bss)
_ebss = .;
}
_end = .;
}
}

View File

@ -15,6 +15,7 @@
#include "syscall/syscall.h"
#include "smp/smp.h"
#include <smp/ipi.h>
#include <sched/sched.h>
#include "driver/multiboot2/multiboot2.h"
#include "driver/acpi/acpi.h"
@ -147,8 +148,8 @@ void system_initialize()
{
// 初始化printk
printk_init(8, 16);
kinfo("Kernel Starting...");
load_TR(10); // 加载TR寄存器
@ -190,12 +191,24 @@ void system_initialize()
// test_mm();
// 再初始化进程模块。顺序不能调转
// sched_init();
// process_init();
}
//操作系统内核从这里开始执行
void Start_Kernel(void)
{
// 获取multiboot2的信息
uint64_t mb2_info, mb2_magic;
__asm__ __volatile__("movq %%r15, %0 \n\t"
"movq %%r14, %1 \n\t"
: "=r"(mb2_info), "=r"(mb2_magic)::"memory");
mb2_info &= 0xffffffff;
mb2_magic &= 0xffffffff;
multiboot2_magic = mb2_magic;
multiboot2_boot_info_addr = mb2_info+PAGE_OFFSET;
system_initialize();
/*

View File

@ -6,7 +6,7 @@
ul Total_Memory = 0;
ul total_2M_pages = 0;
static ul root_page_table_phys_addr=0; // 内核层根页表的物理地址
void mm_init()
{
kinfo("Initializing memory management unit...");
@ -190,7 +190,7 @@ void mm_init()
}
global_CR3 = get_CR3();
//root_page_table_phys_addr = global_CR3;
kdebug("global_CR3\t:%#018lx", global_CR3);
kdebug("*global_CR3\t:%#018lx", *phys_2_virt(global_CR3) & (~0xff));
kdebug("**global_CR3\t:%#018lx", *phys_2_virt(*phys_2_virt(global_CR3) & (~0xff)) & (~0xff));
@ -539,7 +539,7 @@ void mm_map_phys_addr(ul virt_addr_start, ul phys_addr_start, ul length, ul flag
{
global_CR3 = get_CR3();
// 计算帧缓冲区的线性地址对应的pml4页表项的地址
// 计算线性地址对应的pml4页表项的地址
ul *tmp = phys_2_virt((ul *)((ul)global_CR3 & (~0xfffUL)) + ((virt_addr_start >> PAGE_GDT_SHIFT) & 0x1ff));
if (*tmp == 0)
{
@ -566,5 +566,47 @@ void mm_map_phys_addr(ul virt_addr_start, ul phys_addr_start, ul length, ul flag
set_pdt(tmp1, mk_pdt((ul)phys_addr_start + i, flags));
}
flush_tlb();
}
/**
* @brief
*
* @param proc_page_table_addr
* @param virt_addr_start
* @param phys_addr_start
* @param length
* @param user 访
*/
void mm_map_proc_page_table(ul *proc_page_table_addr, ul virt_addr_start, ul phys_addr_start, ul length, ul flags, bool user)
{
// 计算线性地址对应的pml4页表项的地址
ul *tmp = (ul *)((ul)proc_page_table_addr & (~0xfffUL)) + ((virt_addr_start >> PAGE_GDT_SHIFT) & 0x1ff);
if (*tmp == 0)
{
ul *virt_addr = kmalloc(PAGE_4K_SIZE, 0);
set_pml4t(tmp, mk_pml4t(virt_2_phys(virt_addr), (user ? PAGE_USER_PGT : PAGE_KERNEL_PGT)));
}
tmp = (ul *)(*tmp & (~0xfffUL)) + ((virt_addr_start >> PAGE_1G_SHIFT) & 0x1ff);
if (*tmp == 0)
{
ul *virt_addr = kmalloc(PAGE_4K_SIZE, 0);
set_pdpt(tmp, mk_pdpt(virt_2_phys(virt_addr), (user ? PAGE_USER_DIR : PAGE_KERNEL_DIR)));
}
ul *tmp1;
// 初始化2M物理页
for (ul i = 0; i < (length); i += PAGE_2M_SIZE)
{
// 计算当前2M物理页对应的pdt的页表项的物理地址
tmp1 = ((ul *)(*tmp & (~0xfffUL)) + (((ul)(virt_addr_start + i) >> PAGE_2M_SHIFT) & 0x1ff));
// 页面写穿,禁止缓存
set_pdt(tmp1, mk_pdt((ul)phys_addr_start + i, flags | (user ? PAGE_USER_PAGE : PAGE_KERNEL_PAGE)));
}
flush_tlb();
}

View File

@ -7,13 +7,13 @@
#define PTRS_PER_PGT 512
// 内核层的起始地址
#define PAGE_OFFSET ((unsigned long)0x000000)
#define KERNEL_BASE_PHYS_ADDR ((unsigned long)0x100000)
#define PAGE_OFFSET ((unsigned long)0xffff800000000000)
#define KERNEL_BASE_PHYS_ADDR ((unsigned long)0xffff800000000000)
#define PAGE_4K_SHIFT 12
#define PAGE_2M_SHIFT 21
#define PAGE_1G_SHIFT 30
#define PAGE_GDT_SHIFT 39
#define PAGE_GDT_SHIFT 39
// 不同大小的页的容量
#define PAGE_4K_SIZE (1UL << PAGE_4K_SHIFT)
@ -36,13 +36,13 @@
#define Phy_to_2M_Page(kaddr) (memory_management_struct.pages_struct + ((unsigned long)(kaddr) >> PAGE_2M_SHIFT))
// 在这个地址以上的虚拟空间,用来进行特殊的映射
#define SPECIAL_MEMOEY_MAPPING_VIRT_ADDR_BASE 0xffff800000000000UL
#define SPECIAL_MEMOEY_MAPPING_VIRT_ADDR_BASE 0xffffa00000000000UL
#define FRAME_BUFFER_MAPPING_OFFSET 0x3000000UL
#define ACPI_RSDT_MAPPING_OFFSET 0x7000000UL
#define ACPI_XSDT_MAPPING_OFFSET 0x9000000UL
#define IO_APIC_MAPPING_OFFSET 0xfec00000UL
#define LOCAL_APIC_MAPPING_OFFSET 0xfee00000UL
#define AHCI_MAPPING_OFFSET 0xff200000UL // AHCI 映射偏移量,之后使用了4M的地址
#define AHCI_MAPPING_OFFSET 0xff200000UL // AHCI 映射偏移量,之后使用了4M的地址
// ===== 内存区域属性 =====
// DMA区域
@ -66,58 +66,59 @@
#define PAGE_KERNEL (1 << 3)
// 共享的页 shared=1 single-use=0
#define PAGE_SHARED (1<<4)
#define PAGE_SHARED (1 << 4)
// =========== 页表项权限 ========
// bit 63 Execution Disable:
#define PAGE_XD (1UL << 63)
#define PAGE_XD (1UL << 63)
// bit 12 Page Attribute Table
#define PAGE_PAT (1UL << 12)
#define PAGE_PAT (1UL << 12)
// bit 8 Global Page:1,global;0,part
#define PAGE_GLOBAL (1UL << 8)
#define PAGE_GLOBAL (1UL << 8)
// bit 7 Page Size:1,big page;0,small page;
#define PAGE_PS (1UL << 7)
#define PAGE_PS (1UL << 7)
// bit 6 Dirty:1,dirty;0,clean;
#define PAGE_DIRTY (1UL << 6)
#define PAGE_DIRTY (1UL << 6)
// bit 5 Accessed:1,visited;0,unvisited;
#define PAGE_ACCESSED (1UL << 5)
#define PAGE_ACCESSED (1UL << 5)
// bit 4 Page Level Cache Disable
#define PAGE_PCD (1UL << 4)
#define PAGE_PCD (1UL << 4)
// bit 3 Page Level Write Through
#define PAGE_PWT (1UL << 3)
#define PAGE_PWT (1UL << 3)
// bit 2 User Supervisor:1,user and supervisor;0,supervisor;
#define PAGE_U_S (1UL << 2)
#define PAGE_U_S (1UL << 2)
// bit 1 Read Write:1,read and write;0,read;
#define PAGE_R_W (1UL << 1)
#define PAGE_R_W (1UL << 1)
// bit 0 Present:1,present;0,no present;
#define PAGE_PRESENT (1UL << 0)
#define PAGE_PRESENT (1UL << 0)
//1,0
#define PAGE_KERNEL_PGT (PAGE_R_W | PAGE_PRESENT)
// 1,0
#define PAGE_KERNEL_PGT (PAGE_R_W | PAGE_PRESENT)
//1,0
#define PAGE_KERNEL_DIR (PAGE_R_W | PAGE_PRESENT)
// 1,0
#define PAGE_KERNEL_DIR (PAGE_R_W | PAGE_PRESENT)
//7,1,0
#define PAGE_KERNEL_PAGE (PAGE_PS | PAGE_R_W | PAGE_PRESENT)
// 7,1,0
#define PAGE_KERNEL_PAGE (PAGE_PS | PAGE_R_W | PAGE_PRESENT)
//2,1,0
#define PAGE_USER_DIR (PAGE_U_S | PAGE_R_W | PAGE_PRESENT)
#define PAGE_USER_PGT (PAGE_U_S | PAGE_R_W | PAGE_PRESENT)
//7,2,1,0
#define PAGE_USER_PAGE (PAGE_PS | PAGE_U_S | PAGE_R_W | PAGE_PRESENT)
// 2,1,0
#define PAGE_USER_DIR (PAGE_U_S | PAGE_R_W | PAGE_PRESENT)
// 7,2,1,0
#define PAGE_USER_PAGE (PAGE_PS | PAGE_U_S | PAGE_R_W | PAGE_PRESENT)
// ===== 错误码定义 ====
// 物理页结构体为空
@ -227,7 +228,7 @@ extern char _end;
// 每个区域的索引
int ZONE_DMA_INDEX = 0;
int ZONE_NORMAL_INDEX = 0; // low 1GB RAM ,was mapped in pagetable
int ZONE_NORMAL_INDEX = 0; // low 1GB RAM ,was mapped in pagetable
int ZONE_UNMAPPED_INDEX = 0; // above 1GB RAM,unmapped in pagetable
ul *global_CR3 = NULL;
@ -272,9 +273,9 @@ struct Page *alloc_pages(unsigned int zone_select, int num, ul flags);
/**
* @brief 0
*
*
* @param p
* @return unsigned long
* @return unsigned long
*/
unsigned long page_clean(struct Page *page);
@ -288,20 +289,20 @@ void free_pages(struct Page *page, int number);
/**
* @brief Get the page's attr
*
*
* @param page
* @return ul
*/
ul get_page_attr(struct Page* page);
ul get_page_attr(struct Page *page);
/**
* @brief Set the page's attr
*
*
* @param page
* @param flags
* @return ul
*/
ul set_page_attr(struct Page* page, ul flags);
ul set_page_attr(struct Page *page, ul flags);
/**
* @brief
@ -354,9 +355,20 @@ void init_frame_buffer();
/**
* @brief
*
*
* @param virt_addr_start
* @param phys_addr_start
* @param length
*/
void mm_map_phys_addr(ul virt_addr_start, ul phys_addr_start, ul length, ul flags);
void mm_map_phys_addr(ul virt_addr_start, ul phys_addr_start, ul length, ul flags);
/**
* @brief
*
* @param proc_page_table_addr
* @param virt_addr_start
* @param phys_addr_start
* @param length
* @param user 访
*/
void mm_map_proc_page_table(ul *proc_page_table_addr, ul virt_addr_start, ul phys_addr_start, ul length, ul flags, bool user);