o3能运行

This commit is contained in:
fslongjin 2022-08-01 20:40:27 +08:00
parent 58681fd34a
commit e806bbc0c8
23 changed files with 118 additions and 57 deletions

View File

@ -113,7 +113,9 @@
"ia64_msi.h": "c",
"errno.h": "c",
"bug.h": "c",
"apic_timer.h": "c"
"apic_timer.h": "c",
"preempt.h": "c",
"softirq.h": "c"
},
"C_Cpp.errorSquiggles": "Enabled",
"esbonio.sphinx.confDir": ""

View File

@ -7,7 +7,7 @@ export ARCH=__x86_64__
export ROOT_PATH=$(shell pwd)
export DEBUG=DEBUG
export GLOBAL_CFLAGS := -mcmodel=large -fno-builtin -m64 -O1 -fno-stack-protector -D $(ARCH)
export GLOBAL_CFLAGS := -mcmodel=large -fno-builtin -m64 -fno-stack-protector -D $(ARCH)
ifeq ($(DEBUG), DEBUG)
GLOBAL_CFLAGS += -g

View File

@ -10,7 +10,7 @@ LIB_FILES := $(foreach DIR,$(DIR_LIB),$(addprefix $(DIR)/,$(lib_patterns)))
# 控制操作系统使用的中断控制器 _INTR_8259A_ _INTR_APIC_
PIC := _INTR_APIC_
CFLAGS = $(GLOBAL_CFLAGS) -D $(PIC) -I $(shell pwd)
CFLAGS = $(GLOBAL_CFLAGS) -D $(PIC) -I $(shell pwd) -O1
export ASFLAGS := --64

View File

@ -10,7 +10,8 @@
#include <driver/uart/uart.h>
#include <driver/video/video.h>
#include "math.h"
#pragma GCC push_options
#pragma GCC optimize("O0")
struct printk_screen_info pos;
extern ul VBE_FB_phys_addr; // 由bootloader传来的帧缓存区的物理地址
static spinlock_t printk_lock;
@ -184,7 +185,9 @@ static void auto_newline()
#endif
pos.y = pos.max_y;
int lines_to_scroll = 1;
barrier();
scroll(true, lines_to_scroll * pos.char_size_y, sw_show_scroll_animation);
barrier();
pos.y -= (lines_to_scroll - 1);
}
}
@ -835,7 +838,6 @@ static int scroll(bool direction, int pixels, bool animation)
int md = pixels % pos.char_size_y;
if (md)
pixels = pixels + pos.char_size_y - md;
if (animation == false)
return do_scroll(direction, pixels);
else
@ -957,3 +959,5 @@ int sprintk(char *buf, const char *fmt, ...)
return count;
}
#pragma GCC pop_options

View File

@ -2,7 +2,8 @@
// Created by longjin on 2022/1/21.
//
#pragma once
#pragma GCC push_options
#pragma GCC optimize("O0")
#define PAD_ZERO 1 // 0填充
#define LEFT 2 // 靠左对齐
#define RIGHT 4 // 靠右对齐
@ -124,3 +125,4 @@ void printk_disable_animation();
* @return int
*/
int sprintk(char *buf, const char *fmt, ...);
#pragma GCC pop_options

View File

@ -2,6 +2,8 @@
#include <common/compiler.h>
#include <common/kprint.h>
#pragma GCC push_options
#pragma GCC optimize("O0")
/**
* @brief condition为true时输出警告信息
*
@ -19,3 +21,4 @@
goto to; \
unlikely(__ret_warn_on); \
})
#pragma GCC pop_options

View File

@ -96,27 +96,7 @@ void apic_io_apic_init()
// 不需要手动启动IO APIC只要初始化了RTE寄存器之后io apic就会自动启用了。
// 而且不是每台电脑都有RCBA寄存器因此不需要手动启用IO APIC
/*
// get RCBA address
io_out32(0xcf8, 0x8000f8f0);
uint x = io_in32(0xcfc);
uint *p;
printk_color(RED, BLACK, "Get RCBA Address:%#010x\n", x);
x = x & 0xffffc000UL;
printk_color(RED, BLACK, "Get RCBA Address:%#010x\n", x);
// get OIC address
if (x > 0xfec00000 && x < 0xfee00000)
{
p = (unsigned int *)(x + 0x31feUL-apic_ioapic_map.addr_phys+apic_ioapic_map.virtual_index_addr);
}
// enable IOAPIC
x = (*p & 0xffffff00) | 0x100;
io_mfence();
*p = x;
io_mfence();
*/
}
/**

View File

@ -5,6 +5,9 @@
#include <exception/irq.h>
#include <mm/mm.h>
#pragma GCC push_options
#pragma GCC optimize("O0")
#define APIC_SUCCESS 0
#define APIC_E_NOTFOUND 1
@ -319,3 +322,5 @@ void apic_local_apic_edge_ack(ul irq_num); // local apic边沿触发 应答
*/
void apic_make_rte_entry(struct apic_IO_APIC_RTE_entry *entry, uint8_t vector, uint8_t deliver_mode, uint8_t dest_mode,
uint8_t deliver_status, uint8_t polarity, uint8_t irr, uint8_t trigger, uint8_t mask, uint8_t dest_apicID);
#pragma GCC pop_options

View File

@ -11,9 +11,13 @@ uint64_t apic_timer_ticks_result = 0;
void apic_timer_enable(uint64_t irq_num)
{
// 启动apic定时器
io_mfence();
uint64_t val = apic_timer_get_LVT();
io_mfence();
val &= (~APIC_LVT_INT_MASKED);
io_mfence();
apic_timer_write_LVT(val);
io_mfence();
}
void apic_timer_disable(uint64_t irq_num)
@ -31,18 +35,24 @@ void apic_timer_disable(uint64_t irq_num)
uint64_t apic_timer_install(ul irq_num, void *arg)
{
// 设置div16
io_mfence();
apic_timer_stop();
io_mfence();
apic_timer_set_div(APIC_TIMER_DIVISOR);
io_mfence();
// 设置初始计数
apic_timer_set_init_cnt(*(uint64_t *)arg);
io_mfence();
// 填写LVT
apic_timer_set_LVT(APIC_TIMER_IRQ_NUM, 1, APIC_LVT_Timer_Periodic);
io_mfence();
}
void apic_timer_uninstall(ul irq_num)
{
apic_timer_write_LVT(APIC_LVT_INT_MASKED);
io_mfence();
}
hardware_intr_controller apic_timer_intr_controller =
@ -65,6 +75,7 @@ void apic_timer_handler(uint64_t number, uint64_t param, struct pt_regs *regs)
{
sched_update_jiffies();
io_mfence();
}
/**

View File

@ -82,4 +82,4 @@ extern uint64_t apic_timer_ticks_result;
*/
void apic_timer_init();
#pragma GCC optimize("O0")
#pragma GCC pop_options

View File

@ -12,6 +12,8 @@
#include <driver/interrupt/apic/apic_timer.h>
#include <common/spinlock.h>
#pragma GCC push_options
#pragma GCC optimize("O0")
static struct acpi_HPET_description_table_t *hpet_table;
static uint64_t HPET_REG_BASE = 0;
static uint32_t HPET_COUNTER_CLK_PERIOD = 0; // 主计数器时间精度(单位:飞秒)
@ -283,3 +285,4 @@ int HPET_init()
// kdebug("HPET_freq=%ld", (long)HPET_freq);
// kdebug("HPET_freq=%lf", HPET_freq);
}
#pragma GCC pop_options

View File

@ -8,9 +8,10 @@
extern spinlock_t xhci_controller_init_lock; // xhci控制器初始化锁
#define MAX_USB_NUM 8 // pci总线上的usb设备的最大数量
#pragma GCC push_options
#pragma GCC optimize("O0")
// 在pci总线上寻找到的usb设备控制器的header
struct pci_device_structure_header_t *usb_pdevs[MAX_USB_NUM];
static struct pci_device_structure_header_t *usb_pdevs[MAX_USB_NUM];
static int usb_pdevs_count = 0;
/**
@ -57,3 +58,4 @@ void usb_init()
}
kinfo("Successfully initialized all usb host controllers!");
}
#pragma GCC pop_options

View File

@ -9,6 +9,7 @@
#include <exception/irq.h>
#include <driver/interrupt/apic/apic.h>
// 由于xhci寄存器读取需要对齐因此禁用GCC优化选项
#pragma GCC push_options
#pragma GCC optimize("O0")

View File

@ -12,6 +12,8 @@
#include <common/kprint.h>
#include <mm/mm.h>
#pragma GCC push_options
#pragma GCC optimize("O0")
//描述符表的结构体
struct desc_struct
{
@ -185,3 +187,5 @@ void set_tss64(unsigned int *Table, unsigned long rsp0, unsigned long rsp1, unsi
*(unsigned long *)(Table + 21) = ist7;
}
#endif
#pragma GCC pop_options

View File

@ -34,11 +34,12 @@
#include <driver/video/video.h>
#include <driver/interrupt/apic/apic_timer.h>
#pragma GCC push_options
#pragma GCC optimize("O3")
unsigned int *FR_address = (unsigned int *)0xb8000; //帧缓存区的地址
ul bsp_idt_size, bsp_gdt_size;
struct memory_desc memory_management_struct = {{0}, 0};
// struct Global_Memory_Descriptor memory_management_struct = {{0}, 0};
void test_slab();
@ -126,13 +127,18 @@ void system_initialize()
current_pcb->preempt_count = 0;
// 先初始化系统调用模块
syscall_init();
io_mfence();
// 再初始化进程模块。顺序不能调转
sched_init();
io_mfence();
timer_init();
// 这里必须加内存屏障,否则会出错
io_mfence();
smp_init();
kdebug("after smp init");
io_mfence();
cpu_init();
ps2_keyboard_init();
@ -146,19 +152,24 @@ void system_initialize()
// process_init();
HPET_init();
io_mfence();
HPET_measure_freq();
io_mfence();
// current_pcb->preempt_count = 0;
// kdebug("cpu_get_core_crysral_freq()=%ld", cpu_get_core_crysral_freq());
process_init();
// 对显示模块进行高级初始化启用double buffer
video_init(true);
io_mfence();
// fat32_init();
HPET_enable();
io_mfence();
// 系统初始化到此结束,剩下的初始化功能应当放在初始内核线程中执行
apic_timer_init();
io_mfence();
}
//操作系统内核从这里开始执行
@ -182,8 +193,9 @@ void Start_Kernel(void)
mb2_magic &= 0xffffffff;
multiboot2_magic = (uint)mb2_magic;
multiboot2_boot_info_addr = mb2_info + PAGE_OFFSET;
io_mfence();
system_initialize();
io_mfence();
while (1)
hlt();
@ -195,3 +207,4 @@ void ignore_int()
while (1)
;
}
#pragma GCC pop_options

View File

@ -11,7 +11,10 @@
static ul Total_Memory = 0;
static ul total_2M_pages = 0;
static ul root_page_table_phys_addr = 0; // 内核层根页表的物理地址
#pragma GCC push_options
#pragma GCC optimize("O0")
struct memory_desc memory_management_struct = {{0}, 0};
/**
* @brief entry数量
*
@ -278,6 +281,7 @@ unsigned long page_init(struct Page *page, ul flags)
if ((!page->ref_counts) || (page->attr & PAGE_SHARED))
{
++page->ref_counts;
barrier();
++page->zone->total_pages_link;
}
return 0;
@ -977,3 +981,4 @@ int8_t mm_is_2M_page(uint64_t paddr)
return 1;
else return 0;
}
#pragma GCC pop_options

View File

@ -145,6 +145,7 @@
do \
{ \
ul tmp; \
io_mfence();\
__asm__ __volatile__( \
"movq %%cr3, %0\n\t" \
"movq %0, %%cr3\n\t" \

View File

@ -1,6 +1,8 @@
#include "slab.h"
#include <common/compiler.h>
#pragma GCC push_options
#pragma GCC optimize("O0")
struct slab kmalloc_cache_group[16] =
{
{32, 0, 0, NULL, NULL, NULL, NULL},
@ -348,9 +350,9 @@ ul slab_init()
kinfo("Initializing SLAB...");
// 将slab的内存池空间放置在mms的后方
ul tmp_addr = memory_management_struct.end_of_struct;
for (int i = 0; i < 16; ++i)
{
io_mfence();
spin_init(&kmalloc_cache_group[i].lock);
// 将slab内存池对象的空间放置在mms的后面并且预留4个unsigned long 的空间以防止内存越界
kmalloc_cache_group[i].cache_pool_entry = (struct slab_obj *)memory_management_struct.end_of_struct;
@ -370,7 +372,7 @@ ul slab_init()
// bmp后方预留4个unsigned long的空间防止内存越界,且按照8byte进行对齐
memory_management_struct.end_of_struct = (ul)(memory_management_struct.end_of_struct + kmalloc_cache_group[i].cache_pool_entry->bmp_len + (sizeof(ul) << 2)) & (~(sizeof(ul) - 1));
io_mfence();
// @todo此处可优化直接把所有位设置为0然后再对部分不存在对应的内存对象的位设置为1
memset(kmalloc_cache_group[i].cache_pool_entry->bmp, 0xff, kmalloc_cache_group[i].cache_pool_entry->bmp_len);
for (int j = 0; j < kmalloc_cache_group[i].cache_pool_entry->bmp_count; ++j)
@ -378,6 +380,7 @@ ul slab_init()
kmalloc_cache_group[i].count_total_using = 0;
kmalloc_cache_group[i].count_total_free = kmalloc_cache_group[i].cache_pool_entry->count_free;
io_mfence();
}
struct Page *page = NULL;
@ -388,13 +391,17 @@ ul slab_init()
ul page_num = 0;
for (int i = PAGE_2M_ALIGN(virt_2_phys(tmp_addr)) >> PAGE_2M_SHIFT; i <= tmp_page_mms_end; ++i)
{
page = memory_management_struct.pages_struct + i;
page_num = page->addr_phys >> PAGE_2M_SHIFT;
*(memory_management_struct.bmp + (page_num >> 6)) |= (1UL << (page_num % 64));
++page->zone->count_pages_using;
io_mfence();
--page->zone->count_pages_free;
page_init(page, PAGE_KERNEL_INIT | PAGE_KERNEL | PAGE_PGT_MAPPED);
}
io_mfence();
// 为slab内存池对象分配内存空间
ul *virt = NULL;
@ -406,8 +413,11 @@ ul slab_init()
page = Virt_To_2M_Page(virt);
page_num = page->addr_phys >> PAGE_2M_SHIFT;
*(memory_management_struct.bmp + (page_num >> 6)) |= (1UL << (page_num % 64));
++page->zone->count_pages_using;
io_mfence(); // 该位置必须加一个mfence否则O3优化运行时会报错
--page->zone->count_pages_free;
page_init(page, PAGE_PGT_MAPPED | PAGE_KERNEL | PAGE_KERNEL_INIT);
@ -697,3 +707,4 @@ unsigned long kfree(void *address)
kBUG("kfree(): Can't free memory.");
return ECANNOT_FREE_MEM;
}
#pragma GCC pop_options

View File

@ -18,8 +18,8 @@
#include <filesystem/VFS/VFS.h>
#include <common/wait_queue.h>
// #pragma GCC push_options
// #pragma GCC optimize("O0")
#pragma GCC push_options
#pragma GCC optimize("O0")
// 进程最大可拥有的文件描述符数量
#define PROC_MAX_FD_NUM 16
@ -365,4 +365,4 @@ extern struct mm_struct initial_mm;
extern struct thread_struct initial_thread;
extern union proc_union initial_proc_union;
extern struct process_control_block *initial_proc[MAX_CPU_NUM];
// #pragma GCC pop_options
#pragma GCC pop_options

View File

@ -161,4 +161,4 @@ void sched_init()
sched_cfs_ready_queue[i].proc_queue.virtual_runtime = 0x7fffffffffffffff;
}
}
#pragma GCC optimize("O0")
#pragma GCC pop_options

View File

@ -3,6 +3,8 @@
#include <common/glib.h>
#include <process/process.h>
#pragma GCC push_options
#pragma GCC optimize("O0")
// @todo: 用红黑树重写cfs的队列
struct sched_queue_t
{
@ -46,3 +48,5 @@ void sched_init();
*
*/
void sched_update_jiffies();
#pragma GCC pop_options

View File

@ -11,7 +11,7 @@
#include "ipi.h"
#pragma GCC push_options
#pragma GCC optimize("O0")
#pragma GCC optimize("O1")
void ipi_0xc8_handler(uint64_t irq_num, uint64_t param, struct pt_regs *regs); // 由BSP转发的HPET中断处理函数
static spinlock_t multi_core_starting_lock; // 多核启动锁
@ -50,19 +50,20 @@ void smp_init()
kdebug("total_processor_num=%d", total_processor_num);
for (int i = 1; i < total_processor_num; ++i) // i从1开始不初始化bsp
{
io_mfence();
if (proc_local_apic_structs[i]->ACPI_Processor_UID == 0)
--total_processor_num;
if (proc_local_apic_structs[i]->local_apic_id > total_processor_num)
{
--total_processor_num;
continue;}
continue;
}
kdebug("[core %d] acpi processor UID=%d, APIC ID=%d, flags=%#010lx", i, proc_local_apic_structs[i]->ACPI_Processor_UID, proc_local_apic_structs[i]->local_apic_id, proc_local_apic_structs[i]->flags);
spin_lock(&multi_core_starting_lock);
preempt_enable(); // 由于ap处理器的pcb与bsp的不同因此ap处理器放锁时bsp的自旋锁持有计数不会发生改变,需要手动恢复preempt count
current_starting_cpu = proc_local_apic_structs[i]->local_apic_id;
// 为每个AP处理器分配栈空间
cpu_core_info[current_starting_cpu].stack_start = (uint64_t)kmalloc(STACK_SIZE, 0) + STACK_SIZE;
cpu_core_info[current_starting_cpu].ist_stack_start = (uint64_t)(kmalloc(STACK_SIZE, 0)) + STACK_SIZE;
@ -78,7 +79,7 @@ void smp_init()
memset(&initial_tss[current_starting_cpu], 0, sizeof(struct tss_struct));
set_tss_descriptor(10 + (current_starting_cpu * 2), (void *)(cpu_core_info[current_starting_cpu].tss_vaddr));
io_mfence();
set_tss64((uint *)cpu_core_info[current_starting_cpu].tss_vaddr, cpu_core_info[current_starting_cpu].stack_start, cpu_core_info[current_starting_cpu].stack_start, cpu_core_info[current_starting_cpu].stack_start,
cpu_core_info[current_starting_cpu].ist_stack_start, cpu_core_info[current_starting_cpu].ist_stack_start, cpu_core_info[current_starting_cpu].ist_stack_start, cpu_core_info[current_starting_cpu].ist_stack_start, cpu_core_info[current_starting_cpu].ist_stack_start, cpu_core_info[current_starting_cpu].ist_stack_start, cpu_core_info[current_starting_cpu].ist_stack_start);

View File

@ -0,0 +1,9 @@
import os
start = int(input("Start from: "))
end = int(input("End at: "))
for i in range(start, end+1):
print("Deleting: " + str(i))
os.system("sudo losetup -d /dev/loop" + str(i))
print("Done!")