使用cargo管理一些C文件的编译,并且移动部分汇编到arch目录 (#447)

* 使用cargo管理main.c的编译

* 使用build-scripts编译架构相关的c代码

* 删除elf.h
This commit is contained in:
LoGin
2023-11-17 21:25:15 +08:00
committed by GitHub
parent e4600f7f7d
commit 46e234aef6
36 changed files with 556 additions and 1683 deletions

View File

@ -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."

View File

@ -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."

View File

@ -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."

View File

@ -300,7 +300,7 @@ ENTRY(_start64)
// 50-100M025
mov $12800, %ecx
.fill_pt_64_2:
mov $0, 0(%eax)
movq $0, 0(%eax)
add $8, %eax
loop .fill_pt_64_2

View File

@ -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;
}

View 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