mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-19 09:06:32 +00:00
使用cargo管理一些C文件的编译,并且移动部分汇编到arch目录 (#447)
* 使用cargo管理main.c的编译 * 使用build-scripts编译架构相关的c代码 * 删除elf.h
This commit is contained in:
@ -1,17 +0,0 @@
|
||||
|
||||
CFLAGS += -I .
|
||||
|
||||
ifeq ($(ARCH), __x86_64__)
|
||||
kernel_arch_subdirs:=x86_64
|
||||
endif
|
||||
|
||||
all:
|
||||
@list='$(kernel_arch_subdirs)'; for subdir in $$list; do \
|
||||
echo "make all in $$subdir";\
|
||||
cd $$subdir;\
|
||||
$(MAKE) all CFLAGS="$(CFLAGS)" ;\
|
||||
cd ..;\
|
||||
done
|
||||
|
||||
clean:
|
||||
echo "Done."
|
@ -1,23 +0,0 @@
|
||||
|
||||
CFLAGS += -I .
|
||||
|
||||
kernel_arch_x86_64_subdirs:= asm
|
||||
|
||||
kernel_arch_x86_64_objs:= $(shell find ./*.c)
|
||||
|
||||
ECHO:
|
||||
@echo "$@"
|
||||
|
||||
|
||||
$(kernel_arch_x86_64_objs): ECHO
|
||||
$(CC) $(CFLAGS) -c $@ -o $@.o
|
||||
|
||||
$(kernel_arch_x86_64_subdirs): ECHO
|
||||
$(MAKE) -C $@ all CFLAGS="$(CFLAGS)" ASFLAGS="$(ASFLAGS)"
|
||||
|
||||
all: $(kernel_arch_x86_64_objs) $(kernel_arch_x86_64_subdirs)
|
||||
|
||||
|
||||
|
||||
clean:
|
||||
echo "Done."
|
@ -1,22 +0,0 @@
|
||||
|
||||
CFLAGS += -I .
|
||||
|
||||
# kernel_arch_x86_64_asm_subdirs:=
|
||||
|
||||
kernel_arch_x86_64_asm_objs:= $(shell find ./*.c)
|
||||
|
||||
ECHO:
|
||||
@echo "$@"
|
||||
|
||||
|
||||
$(kernel_arch_x86_64_asm_objs): ECHO
|
||||
$(CC) $(CFLAGS) -c $@ -o $@.o
|
||||
|
||||
# $(kernel_arch_x86_64_asm_subdirs): ECHO
|
||||
# $(MAKE) -C $@ all CFLAGS="$(CFLAGS)" ASFLAGS="$(ASFLAGS)"
|
||||
|
||||
all: $(kernel_arch_x86_64_asm_objs)
|
||||
|
||||
|
||||
clean:
|
||||
echo "Done."
|
@ -300,7 +300,7 @@ ENTRY(_start64)
|
||||
// 50-100M填0,共25个页表
|
||||
mov $12800, %ecx
|
||||
.fill_pt_64_2:
|
||||
mov $0, 0(%eax)
|
||||
movq $0, 0(%eax)
|
||||
add $8, %eax
|
||||
loop .fill_pt_64_2
|
||||
|
||||
|
@ -1,16 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#include <DragonOS/stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <common/stddef.h>
|
||||
|
||||
// 定义类型的缩写
|
||||
typedef unsigned char uchar;
|
||||
typedef unsigned short ushort;
|
||||
typedef unsigned int uint;
|
||||
typedef unsigned long ul;
|
||||
typedef unsigned long long int ull;
|
||||
typedef long long int ll;
|
||||
|
||||
#define sti() __asm__ __volatile__("sti\n\t" :: \
|
||||
: "memory") //开启外部中断
|
||||
: "memory") // 开启外部中断
|
||||
#define cli() __asm__ __volatile__("cli\n\t" :: \
|
||||
: "memory") //关闭外部中断
|
||||
: "memory") // 关闭外部中断
|
||||
#define nop() __asm__ __volatile__("nop\n\t")
|
||||
#define hlt() __asm__ __volatile__("hlt\n\t")
|
||||
#define pause() asm volatile("pause\n\t"); // 处理器等待一段时间
|
||||
|
||||
//内存屏障
|
||||
// 内存屏障
|
||||
#define io_mfence() __asm__ __volatile__("mfence\n\t" :: \
|
||||
: "memory") // 在mfence指令前的读写操作必须在mfence指令后的读写操作前完成。
|
||||
#define io_sfence() __asm__ __volatile__("sfence\n\t" :: \
|
||||
@ -54,6 +64,22 @@ unsigned long *get_rsp()
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 验证地址空间是否为用户地址空间
|
||||
*
|
||||
* @param addr_start 地址起始值
|
||||
* @param length 地址长度
|
||||
* @return true
|
||||
* @return false
|
||||
*/
|
||||
bool verify_area(uint64_t addr_start, uint64_t length)
|
||||
{
|
||||
if ((addr_start + length) <= 0x00007fffffffffffUL) // 用户程序可用的的地址空间应<= 0x00007fffffffffffUL
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 读取rbp寄存器的值(存储了页目录的基地址)
|
||||
*
|
||||
@ -146,4 +172,248 @@ uint64_t get_rflags()
|
||||
"popfq \n\t"
|
||||
: "=r"(tmp)::"memory");
|
||||
return tmp;
|
||||
}
|
||||
|
||||
void *memset(void *dst, unsigned char C, ul size)
|
||||
{
|
||||
|
||||
int d0, d1;
|
||||
unsigned long tmp = C * 0x0101010101010101UL;
|
||||
__asm__ __volatile__("cld \n\t"
|
||||
"rep \n\t"
|
||||
"stosq \n\t"
|
||||
"testb $4, %b3 \n\t"
|
||||
"je 1f \n\t"
|
||||
"stosl \n\t"
|
||||
"1:\ttestb $2, %b3 \n\t"
|
||||
"je 2f\n\t"
|
||||
"stosw \n\t"
|
||||
"2:\ttestb $1, %b3 \n\t"
|
||||
"je 3f \n\t"
|
||||
"stosb \n\t"
|
||||
"3: \n\t"
|
||||
: "=&c"(d0), "=&D"(d1)
|
||||
: "a"(tmp), "q"(size), "0"(size / 8), "1"(dst)
|
||||
: "memory");
|
||||
return dst;
|
||||
}
|
||||
|
||||
void *memset_c(void *dst, uint8_t c, size_t count)
|
||||
{
|
||||
uint8_t *xs = (uint8_t *)dst;
|
||||
|
||||
while (count--)
|
||||
*xs++ = c;
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 内存拷贝函数
|
||||
*
|
||||
* @param dst 目标数组
|
||||
* @param src 源数组
|
||||
* @param Num 字节数
|
||||
* @return void*
|
||||
*/
|
||||
static void *memcpy(void *dst, const void *src, long Num)
|
||||
{
|
||||
int d0 = 0, d1 = 0, d2 = 0;
|
||||
__asm__ __volatile__("cld \n\t"
|
||||
"rep \n\t"
|
||||
"movsq \n\t"
|
||||
"testb $4,%b4 \n\t"
|
||||
"je 1f \n\t"
|
||||
"movsl \n\t"
|
||||
"1:\ttestb $2,%b4 \n\t"
|
||||
"je 2f \n\t"
|
||||
"movsw \n\t"
|
||||
"2:\ttestb $1,%b4 \n\t"
|
||||
"je 3f \n\t"
|
||||
"movsb \n\t"
|
||||
"3: \n\t"
|
||||
: "=&c"(d0), "=&D"(d1), "=&S"(d2)
|
||||
: "0"(Num / 8), "q"(Num), "1"(dst), "2"(src)
|
||||
: "memory");
|
||||
return dst;
|
||||
}
|
||||
|
||||
// 从io口读入8个bit
|
||||
unsigned char io_in8(unsigned short port)
|
||||
{
|
||||
unsigned char ret = 0;
|
||||
__asm__ __volatile__("inb %%dx, %0 \n\t"
|
||||
"mfence \n\t"
|
||||
: "=a"(ret)
|
||||
: "d"(port)
|
||||
: "memory");
|
||||
return ret;
|
||||
}
|
||||
|
||||
// 从io口读入32个bit
|
||||
unsigned int io_in32(unsigned short port)
|
||||
{
|
||||
unsigned int ret = 0;
|
||||
__asm__ __volatile__("inl %%dx, %0 \n\t"
|
||||
"mfence \n\t"
|
||||
: "=a"(ret)
|
||||
: "d"(port)
|
||||
: "memory");
|
||||
return ret;
|
||||
}
|
||||
|
||||
// 输出8个bit到输出端口
|
||||
void io_out8(unsigned short port, unsigned char value)
|
||||
{
|
||||
__asm__ __volatile__("outb %0, %%dx \n\t"
|
||||
"mfence \n\t"
|
||||
:
|
||||
: "a"(value), "d"(port)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
// 输出32个bit到输出端口
|
||||
void io_out32(unsigned short port, unsigned int value)
|
||||
{
|
||||
__asm__ __volatile__("outl %0, %%dx \n\t"
|
||||
"mfence \n\t"
|
||||
:
|
||||
: "a"(value), "d"(port)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 从端口读入n个word到buffer
|
||||
*
|
||||
*/
|
||||
#define io_insw(port, buffer, nr) \
|
||||
__asm__ __volatile__("cld;rep;insw;mfence;" ::"d"(port), "D"(buffer), "c"(nr) \
|
||||
: "memory")
|
||||
|
||||
/**
|
||||
* @brief 从输出buffer中的n个word到端口
|
||||
*
|
||||
*/
|
||||
#define io_outsw(port, buffer, nr) \
|
||||
__asm__ __volatile__("cld;rep;outsw;mfence;" ::"d"(port), "S"(buffer), "c"(nr) \
|
||||
: "memory")
|
||||
|
||||
/**
|
||||
* @brief 从用户空间搬运数据到内核空间
|
||||
*
|
||||
* @param dst 目的地址
|
||||
* @param src 源地址
|
||||
* @param size 搬运的大小
|
||||
* @return uint64_t
|
||||
*/
|
||||
static inline uint64_t copy_from_user(void *dst, void *src, uint64_t size)
|
||||
{
|
||||
uint64_t tmp0, tmp1;
|
||||
if (!verify_area((uint64_t)src, size))
|
||||
return 0;
|
||||
|
||||
/**
|
||||
* @brief 先每次搬运8 bytes,剩余就直接一个个byte搬运
|
||||
*
|
||||
*/
|
||||
asm volatile("rep \n\t"
|
||||
"movsq \n\t"
|
||||
"movq %3, %0 \n\t"
|
||||
"rep \n\t"
|
||||
"movsb \n\t"
|
||||
: "=&c"(size), "=&D"(tmp0), "=&S"(tmp1)
|
||||
: "r"(size & 7), "0"(size >> 3), "1"(dst), "2"(src)
|
||||
: "memory");
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 从内核空间搬运数据到用户空间
|
||||
*
|
||||
* @param dst 目的地址
|
||||
* @param src 源地址
|
||||
* @param size 搬运的大小
|
||||
* @return uint64_t
|
||||
*/
|
||||
static inline uint64_t copy_to_user(void *dst, void *src, uint64_t size)
|
||||
{
|
||||
if (verify_area((uint64_t)src, size))
|
||||
return 0;
|
||||
|
||||
/**
|
||||
* @brief 先每次搬运8 bytes,剩余就直接一个个byte搬运
|
||||
*
|
||||
*/
|
||||
// todo:编译有bug
|
||||
// asm volatile("rep \n\t"
|
||||
// "movsq \n\t"
|
||||
// "movq %3, %0 \n\t"
|
||||
// "rep \n\t"
|
||||
// "movsb \n\t"
|
||||
// : "=&c"(size), "=&D"(tmp0), "=&S"(tmp1)
|
||||
// : "r"(size & 7), "0"(size >> 3), "1"(dst), "2"(src)
|
||||
// : "memory");
|
||||
memcpy(dst, src, size);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 往指定地址写入8字节
|
||||
* 防止由于编译器优化导致不支持的内存访问类型(尤其是在mmio的时候)
|
||||
*
|
||||
* @param vaddr 虚拟地址
|
||||
* @param value 要写入的值
|
||||
*/
|
||||
static __always_inline void __write8b(uint64_t vaddr, uint64_t value)
|
||||
{
|
||||
asm volatile("movq %%rdx, 0(%%rax)" ::"a"(vaddr), "d"(value)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 往指定地址写入4字节
|
||||
* 防止由于编译器优化导致不支持的内存访问类型(尤其是在mmio的时候)
|
||||
*
|
||||
* @param vaddr 虚拟地址
|
||||
* @param value 要写入的值
|
||||
*/
|
||||
static __always_inline void __write4b(uint64_t vaddr, uint32_t value)
|
||||
{
|
||||
asm volatile("movl %%edx, 0(%%rax)" ::"a"(vaddr), "d"(value)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 从指定地址读取8字节
|
||||
* 防止由于编译器优化导致不支持的内存访问类型(尤其是在mmio的时候)
|
||||
*
|
||||
* @param vaddr 虚拟地址
|
||||
* @return uint64_t 读取到的值
|
||||
*/
|
||||
static __always_inline uint64_t __read8b(uint64_t vaddr)
|
||||
{
|
||||
uint64_t retval;
|
||||
asm volatile("movq 0(%%rax), %0"
|
||||
: "=r"(retval)
|
||||
: "a"(vaddr)
|
||||
: "memory");
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 从指定地址读取4字节
|
||||
* 防止由于编译器优化导致不支持的内存访问类型(尤其是在mmio的时候)
|
||||
*
|
||||
* @param vaddr 虚拟地址
|
||||
* @return uint64_t 读取到的值
|
||||
*/
|
||||
static __always_inline uint32_t __read4b(uint64_t vaddr)
|
||||
{
|
||||
uint32_t retval;
|
||||
asm volatile("movl 0(%%rax), %0"
|
||||
: "=d"(retval)
|
||||
: "a"(vaddr)
|
||||
: "memory");
|
||||
return retval;
|
||||
}
|
219
kernel/src/arch/x86_64/init/main.c
Normal file
219
kernel/src/arch/x86_64/init/main.c
Normal file
@ -0,0 +1,219 @@
|
||||
//
|
||||
// Created by longjin on 2022/1/20.
|
||||
//
|
||||
|
||||
#include "common/glib.h"
|
||||
#include "common/kprint.h"
|
||||
#include "common/printk.h"
|
||||
#include "exception/gate.h"
|
||||
#include "exception/irq.h"
|
||||
#include "exception/trap.h"
|
||||
#include "mm/mm.h"
|
||||
#include "mm/slab.h"
|
||||
#include "process/process.h"
|
||||
#include "smp/smp.h"
|
||||
#include "syscall/syscall.h"
|
||||
#include <exception/softirq.h>
|
||||
#include <libs/lib_ui/screen_manager.h>
|
||||
#include <libs/lib_ui/textui.h>
|
||||
#include <sched/sched.h>
|
||||
#include <smp/ipi.h>
|
||||
|
||||
#include <filesystem/vfs/VFS.h>
|
||||
|
||||
#include "driver/acpi/acpi.h"
|
||||
#include "driver/disk/ata.h"
|
||||
#include "driver/keyboard/ps2_keyboard.h"
|
||||
#include "driver/mouse/ps2_mouse.h"
|
||||
#include "driver/multiboot2/multiboot2.h"
|
||||
#include <time/timer.h>
|
||||
|
||||
#include <arch/x86_64/driver/apic/apic_timer.h>
|
||||
#include <virt/kvm/kvm.h>
|
||||
#include <debug/bug.h>
|
||||
|
||||
extern int rs_driver_init();
|
||||
extern void rs_softirq_init();
|
||||
extern void rs_mm_init();
|
||||
extern void rs_kthread_init();
|
||||
extern void rs_init_intertrait();
|
||||
extern void rs_init_before_mem_init();
|
||||
extern int rs_setup_arch();
|
||||
extern void rs_futex_init();
|
||||
extern int rs_hpet_init();
|
||||
extern int rs_hpet_enable();
|
||||
extern int rs_tsc_init();
|
||||
extern void rs_clocksource_boot_finish();
|
||||
extern void rs_timekeeping_init();
|
||||
extern void rs_process_init();
|
||||
extern void rs_textui_init();
|
||||
extern void rs_pci_init();
|
||||
|
||||
ul bsp_idt_size, bsp_gdt_size;
|
||||
|
||||
#pragma GCC push_options
|
||||
#pragma GCC optimize("O0")
|
||||
struct gdtr gdtp;
|
||||
struct idtr idtp;
|
||||
ul _stack_start;
|
||||
void reload_gdt()
|
||||
{
|
||||
|
||||
gdtp.size = bsp_gdt_size - 1;
|
||||
gdtp.gdt_vaddr = (ul)phys_2_virt((ul)&GDT_Table);
|
||||
|
||||
asm volatile("lgdt (%0) \n\t" ::"r"(&gdtp) : "memory");
|
||||
}
|
||||
|
||||
void reload_idt()
|
||||
{
|
||||
|
||||
idtp.size = bsp_idt_size - 1;
|
||||
idtp.idt_vaddr = (ul)phys_2_virt((ul)&IDT_Table);
|
||||
// kdebug("gdtvaddr=%#018lx", p.gdt_vaddr);
|
||||
// kdebug("gdt size=%d", p.size);
|
||||
|
||||
asm volatile("lidt (%0) \n\t" ::"r"(&idtp) : "memory");
|
||||
}
|
||||
|
||||
// 初始化系统各模块
|
||||
void system_initialize()
|
||||
{
|
||||
rs_init_before_mem_init();
|
||||
|
||||
_stack_start =
|
||||
head_stack_start; // 保存init
|
||||
// proc的栈基地址(由于之后取消了地址重映射,因此必须在这里重新保存)
|
||||
kdebug("_stack_start=%#018lx", _stack_start);
|
||||
|
||||
set_current_core_tss(_stack_start, 0);
|
||||
rs_load_current_core_tss();
|
||||
|
||||
cpu_core_info[0].stack_start = _stack_start;
|
||||
|
||||
// 初始化中断描述符表
|
||||
sys_vector_init();
|
||||
// 初始化内存管理单元
|
||||
// mm_init();
|
||||
rs_mm_init();
|
||||
// 内存管理单元初始化完毕后,需要立即重新初始化显示驱动。
|
||||
// 原因是,系统启动初期,framebuffer被映射到48M地址处,
|
||||
// mm初始化完毕后,若不重新初始化显示驱动,将会导致错误的数据写入内存,从而造成其他模块崩溃
|
||||
// 对显示模块进行低级初始化,不启用double buffer
|
||||
|
||||
io_mfence();
|
||||
scm_reinit();
|
||||
rs_textui_init();
|
||||
|
||||
rs_init_intertrait();
|
||||
// kinfo("vaddr:%#018lx", video_frame_buffer_info.vaddr);
|
||||
io_mfence();
|
||||
vfs_init();
|
||||
|
||||
rs_driver_init();
|
||||
|
||||
acpi_init();
|
||||
|
||||
rs_setup_arch();
|
||||
io_mfence();
|
||||
irq_init();
|
||||
rs_process_init();
|
||||
sched_init();
|
||||
|
||||
sti();
|
||||
io_mfence();
|
||||
|
||||
rs_softirq_init();
|
||||
|
||||
syscall_init();
|
||||
io_mfence();
|
||||
|
||||
rs_timekeeping_init();
|
||||
io_mfence();
|
||||
|
||||
rs_timer_init();
|
||||
io_mfence();
|
||||
|
||||
rs_jiffies_init();
|
||||
io_mfence();
|
||||
|
||||
rs_kthread_init();
|
||||
io_mfence();
|
||||
|
||||
io_mfence();
|
||||
rs_clocksource_boot_finish();
|
||||
|
||||
io_mfence();
|
||||
|
||||
cpu_init();
|
||||
|
||||
ps2_keyboard_init();
|
||||
io_mfence();
|
||||
|
||||
rs_pci_init();
|
||||
|
||||
// 这里必须加内存屏障,否则会出错
|
||||
io_mfence();
|
||||
smp_init();
|
||||
|
||||
io_mfence();
|
||||
rs_futex_init();
|
||||
cli();
|
||||
rs_hpet_init();
|
||||
rs_hpet_enable();
|
||||
rs_tsc_init();
|
||||
|
||||
io_mfence();
|
||||
|
||||
kvm_init();
|
||||
|
||||
io_mfence();
|
||||
// 系统初始化到此结束,剩下的初始化功能应当放在初始内核线程中执行
|
||||
|
||||
apic_timer_init();
|
||||
// while(1);
|
||||
io_mfence();
|
||||
sti();
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
|
||||
// 操作系统内核从这里开始执行
|
||||
void Start_Kernel(void)
|
||||
{
|
||||
|
||||
// 获取multiboot2的信息
|
||||
uint64_t mb2_info, mb2_magic;
|
||||
__asm__ __volatile__("movq %%r15, %0 \n\t"
|
||||
"movq %%r14, %1 \n\t"
|
||||
"movq %%r13, %2 \n\t"
|
||||
"movq %%r12, %3 \n\t"
|
||||
: "=r"(mb2_info), "=r"(mb2_magic), "=r"(bsp_gdt_size),
|
||||
"=r"(bsp_idt_size)::"memory");
|
||||
reload_gdt();
|
||||
reload_idt();
|
||||
|
||||
mb2_info &= 0xffffffff;
|
||||
mb2_magic &= 0xffffffff;
|
||||
multiboot2_init(mb2_info, mb2_magic);
|
||||
io_mfence();
|
||||
system_initialize();
|
||||
io_mfence();
|
||||
|
||||
// idle
|
||||
while (1)
|
||||
{
|
||||
// 如果调用的时候,启用了中断,则hlt。否则认为是bug
|
||||
if (get_rflags() & 0x200)
|
||||
{
|
||||
// kdebug("hlt");
|
||||
hlt();
|
||||
}
|
||||
else
|
||||
{
|
||||
BUG_ON(1);
|
||||
pause();
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma GCC pop_options
|
Reference in New Issue
Block a user