mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-09 07:06:47 +00:00
将内核层空间移动到0xffff800000000000
This commit is contained in:
parent
24b351c9ec
commit
05dc7ac73b
4
Makefile
4
Makefile
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -29,15 +29,18 @@ int printk_init(const int char_size_x, const int char_size_y)
|
||||
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;
|
||||
|
||||
// 初始化自旋锁
|
||||
@ -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)
|
||||
{
|
||||
|
@ -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,6 +25,7 @@ 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
|
||||
@ -36,9 +38,11 @@ void ahci_init()
|
||||
// 赋值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,27 +164,27 @@ 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;
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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)))
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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; // 读取计时器数量
|
||||
double x = 1*2;
|
||||
x = 1.0*3.65;
|
||||
//kinfo("HPET CLK_PERIOD=%#03lx Frequency=%f", HPET_COUNTER_CLK_PERIOD, (double)HPET_freq);
|
||||
|
||||
kinfo("HPET CLK_PERIOD=%#03lx Frequency=%f", HPET_COUNTER_CLK_PERIOD, 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);
|
||||
|
169
kernel/head.S
169
kernel/head.S
@ -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
|
||||
@ -403,6 +360,7 @@ entry64:
|
||||
|
||||
movq _stack_start(%rip), %rsp //rsp的地址
|
||||
|
||||
|
||||
// 分支,判断是否为apu
|
||||
movq $0x1b, %rcx // 根据IA32_APIC_BASE.BSP[8]标志位判断处理器是否为apu
|
||||
rdmsr
|
||||
@ -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
|
||||
|
||||
|
@ -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)
|
||||
|
||||
*(.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 = .;
|
||||
}
|
@ -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);
|
||||
|
||||
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();
|
||||
|
||||
/*
|
||||
|
@ -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)
|
||||
{
|
||||
@ -568,3 +568,45 @@ void mm_map_phys_addr(ul virt_addr_start, ul phys_addr_start, ul length, ul flag
|
||||
|
||||
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();
|
||||
}
|
@ -7,8 +7,8 @@
|
||||
#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
|
||||
@ -36,7 +36,7 @@
|
||||
#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
|
||||
@ -112,13 +112,14 @@
|
||||
// 7,1,0
|
||||
#define PAGE_KERNEL_PAGE (PAGE_PS | PAGE_R_W | PAGE_PRESENT)
|
||||
|
||||
#define PAGE_USER_PGT (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)
|
||||
|
||||
|
||||
// ===== 错误码定义 ====
|
||||
// 物理页结构体为空
|
||||
#define EPAGE_NULL 1
|
||||
@ -360,3 +361,14 @@ void init_frame_buffer();
|
||||
* @param length 要映射的区域的长度(字节)
|
||||
*/
|
||||
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);
|
Loading…
x
Reference in New Issue
Block a user