diff --git a/.vscode/settings.json b/.vscode/settings.json index 71e50afa..82dc5551 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -114,7 +114,9 @@ "errno.h": "c", "bug.h": "c", "apic_timer.h": "c", - "sched.h": "c" + "sched.h": "c", + "preempt.h": "c", + "softirq.h": "c" }, "C_Cpp.errorSquiggles": "Enabled", "esbonio.sphinx.confDir": "" diff --git a/Makefile b/Makefile index c17f91e5..1a87b4c1 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ export ARCH=__x86_64__ export ROOT_PATH=$(shell pwd) export DEBUG=DEBUG -export GLOBAL_CFLAGS := -mcmodel=large -fno-builtin -m64 -O0 -fno-stack-protector -D $(ARCH) +export GLOBAL_CFLAGS := -mcmodel=large -fno-builtin -m64 -fno-stack-protector -D $(ARCH) -O1 ifeq ($(DEBUG), DEBUG) GLOBAL_CFLAGS += -g diff --git a/README.md b/README.md index bdea5397..811b8f58 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ - 项目文档 **[docs.DragonOS.org](https://docs.dragonos.org)** - 开源论坛 **[bbs.DragonOS.org](https://bbs.dragonos.org)** - 开发交流QQ群 **115763565** -  +- 代码搜索引擎 [code.DragonOS.org](http://code.dragonos.org)  ## 开发环境 GCC>=8.0 diff --git a/README_EN.md b/README_EN.md index d44c23e4..e2033aa4 100644 --- a/README_EN.md +++ b/README_EN.md @@ -10,7 +10,8 @@ This project is a operating system running on computer which is in X86_ 64 Archi - Home Page **[DragonOS.org](https://dragonos.org)** - Documentation **[docs.DragonOS.org](https://docs.dragonos.org)** - BBS **[bbs.DragonOS.org](https://bbs.dragonos.org)** -  +- QQ group **115763565** +- code search engine [code.DragonOS.org](http://code.dragonos.org)  ## Development Environment diff --git a/kernel/common/cpu.c b/kernel/common/cpu.c index e6845008..4596a844 100644 --- a/kernel/common/cpu.c +++ b/kernel/common/cpu.c @@ -1,7 +1,7 @@ #include "cpu.h" #include "kprint.h" #include "printk.h" - +// #pragma GCC optimize("O0") // cpu支持的最大cpuid指令的基础主功能号 uint Cpu_cpuid_max_Basic_mop; // cpu支持的最大cpuid指令的扩展主功能号 diff --git a/kernel/common/glib.h b/kernel/common/glib.h index 10ee3f69..1a79076f 100644 --- a/kernel/common/glib.h +++ b/kernel/common/glib.h @@ -93,6 +93,7 @@ struct List static inline void list_init(struct List *list) { list->next = list; + io_mfence(); list->prev = list; } @@ -106,8 +107,11 @@ static inline void list_add(struct List *entry, struct List *node) { node->next = entry->next; + barrier(); node->prev = entry; + barrier(); node->next->prev = node; + barrier(); entry->next = node; } diff --git a/kernel/common/printk.c b/kernel/common/printk.c index d8de0d5d..a2414a80 100644 --- a/kernel/common/printk.c +++ b/kernel/common/printk.c @@ -45,6 +45,8 @@ static uint *get_pos_VBE_FB_addr(); */ static int cls(); +#pragma GCC push_options +#pragma GCC optimize("O0") /** * @brief 滚动窗口(尚不支持向下滚动) * @@ -53,7 +55,7 @@ static int cls(); * @param animation 是否包含滑动动画 */ static int scroll(bool direction, int pixels, bool animation); - +#pragma GCC pop_options /** * @brief 将数字按照指定的要求转换成对应的字符串(2~36进制) * @@ -184,7 +186,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 +839,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 @@ -956,4 +959,5 @@ int sprintk(char *buf, const char *fmt, ...) va_end(args); return count; -} \ No newline at end of file +} + diff --git a/kernel/common/printk.h b/kernel/common/printk.h index 091d304c..a7790499 100644 --- a/kernel/common/printk.h +++ b/kernel/common/printk.h @@ -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 \ No newline at end of file diff --git a/kernel/debug/bug.h b/kernel/debug/bug.h index 59df2cb0..958b0d6f 100644 --- a/kernel/debug/bug.h +++ b/kernel/debug/bug.h @@ -2,6 +2,8 @@ #include #include +#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 \ No newline at end of file diff --git a/kernel/driver/interrupt/apic/apic.c b/kernel/driver/interrupt/apic/apic.c index ce8528c6..1d87c7e8 100644 --- a/kernel/driver/interrupt/apic/apic.c +++ b/kernel/driver/interrupt/apic/apic.c @@ -10,6 +10,8 @@ #include #include +#pragma GCC push_options +#pragma GCC optimize("O0") // 导出定义在irq.c中的中段门表 extern void (*interrupt_table[24])(void); @@ -94,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(); - */ + } /** @@ -650,6 +632,7 @@ void apic_ioapic_edge_ack(ul irq_num) // 边沿触发 * * @param irq_num */ + void apic_local_apic_edge_ack(ul irq_num) { // 向EOI寄存器写入0x00表示结束中断 @@ -660,6 +643,7 @@ void apic_local_apic_edge_ack(ul irq_num) : "memory"); } + /** * @brief 读取指定类型的 Interrupt Control Structure * @@ -734,4 +718,5 @@ void apic_make_rte_entry(struct apic_IO_APIC_RTE_entry *entry, uint8_t vector, u entry->destination.logical.logical_dest = dest_apicID; entry->destination.logical.reserved1 = 0; } -} \ No newline at end of file +} +#pragma GCC pop_options \ No newline at end of file diff --git a/kernel/driver/interrupt/apic/apic.h b/kernel/driver/interrupt/apic/apic.h index 53c6f5e1..95a332ca 100644 --- a/kernel/driver/interrupt/apic/apic.h +++ b/kernel/driver/interrupt/apic/apic.h @@ -5,6 +5,9 @@ #include #include +#pragma GCC push_options +#pragma GCC optimize("O0") + #define APIC_SUCCESS 0 #define APIC_E_NOTFOUND 1 @@ -73,7 +76,7 @@ // 分频配置寄存器(定时器专用) #define LOCAL_APIC_OFFSET_Local_APIC_CLKDIV 0x3e0 -uint32_t RCBA_vaddr = 0;// RCBA寄存器的虚拟地址 +uint32_t RCBA_vaddr = 0; // RCBA寄存器的虚拟地址 /* @@ -318,4 +321,6 @@ void apic_local_apic_edge_ack(ul irq_num); // local apic边沿触发 应答 * @param dest_apicID 目标apicID */ 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); \ No newline at end of file + uint8_t deliver_status, uint8_t polarity, uint8_t irr, uint8_t trigger, uint8_t mask, uint8_t dest_apicID); + +#pragma GCC pop_options \ No newline at end of file diff --git a/kernel/driver/interrupt/apic/apic_timer.c b/kernel/driver/interrupt/apic/apic_timer.c index 9842e099..3f2768f1 100644 --- a/kernel/driver/interrupt/apic/apic_timer.c +++ b/kernel/driver/interrupt/apic/apic_timer.c @@ -4,14 +4,20 @@ #include #include +// #pragma GCC push_options +// #pragma GCC optimize("O0") 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) @@ -29,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 = @@ -63,6 +75,7 @@ void apic_timer_handler(uint64_t number, uint64_t param, struct pt_regs *regs) { sched_update_jiffies(); + io_mfence(); } /** diff --git a/kernel/driver/interrupt/apic/apic_timer.h b/kernel/driver/interrupt/apic/apic_timer.h index 1472b920..1b26e4e1 100644 --- a/kernel/driver/interrupt/apic/apic_timer.h +++ b/kernel/driver/interrupt/apic/apic_timer.h @@ -10,6 +10,8 @@ extern uint64_t apic_timer_ticks_result; #define APIC_TIMER_IRQ_NUM 151 +#pragma GCC push_options +#pragma GCC optimize("O0") /** * @brief 设置apic定时器的分频计数 * @@ -78,4 +80,6 @@ extern uint64_t apic_timer_ticks_result; * @brief 初始化local APIC定时器 * */ -void apic_timer_init(); \ No newline at end of file +void apic_timer_init(); + +#pragma GCC pop_options \ No newline at end of file diff --git a/kernel/driver/timers/HPET/HPET.c b/kernel/driver/timers/HPET/HPET.c index 2099764a..a292b783 100644 --- a/kernel/driver/timers/HPET/HPET.c +++ b/kernel/driver/timers/HPET/HPET.c @@ -12,6 +12,8 @@ #include #include +#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; // 主计数器时间精度(单位:飞秒) @@ -122,7 +124,7 @@ void HPET_measure_freq() // 使用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); - + // 计算HPET0间隔多少个时钟周期触发一次中断 uint64_t clks_to_intr = 0.001 * interval * HPET_freq; // kdebug("clks_to_intr=%#ld", clks_to_intr); @@ -158,9 +160,9 @@ void HPET_measure_freq() // 顺便测定tsc频率 test_tsc_start = rdtsc(); io_mfence(); - while (measure_apic_timer_flag == false) ; + kdebug("wait done"); irq_unregister(34); @@ -283,3 +285,4 @@ int HPET_init() // kdebug("HPET_freq=%ld", (long)HPET_freq); // kdebug("HPET_freq=%lf", HPET_freq); } +#pragma GCC pop_options diff --git a/kernel/driver/usb/usb.c b/kernel/driver/usb/usb.c index 4ff3576d..8f041eb2 100644 --- a/kernel/driver/usb/usb.c +++ b/kernel/driver/usb/usb.c @@ -10,7 +10,7 @@ extern spinlock_t xhci_controller_init_lock; // xhci控制器初始化锁 #define MAX_USB_NUM 8 // pci总线上的usb设备的最大数量 // 在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; /** @@ -34,6 +34,7 @@ void usb_init() // 初始化每个usb控制器 for (int i = 0; i < usb_pdevs_count; ++i) { + io_mfence(); switch (usb_pdevs[i]->ProgIF) { case USB_TYPE_UHCI: @@ -47,6 +48,7 @@ void usb_init() case USB_TYPE_XHCI: // 初始化对应的xhci控制器 xhci_init((struct pci_device_structure_general_device_t *)usb_pdevs[i]); + io_mfence(); break; default: diff --git a/kernel/driver/usb/xhci/xhci.c b/kernel/driver/usb/xhci/xhci.c index 7216077f..c7592e66 100644 --- a/kernel/driver/usb/xhci/xhci.c +++ b/kernel/driver/usb/xhci/xhci.c @@ -9,6 +9,10 @@ #include #include +// 由于xhci寄存器读取需要对齐,因此禁用GCC优化选项 +#pragma GCC push_options +#pragma GCC optimize("O0") + spinlock_t xhci_controller_init_lock = {0}; // xhci控制器初始化锁(在usb_init中被初始化) static int xhci_ctrl_count = 0; // xhci控制器计数 @@ -52,7 +56,6 @@ hardware_intr_controller xhci_hc_intr_controller = 例子:不能在一个32bit的寄存器中的偏移量8的位置开始读取1个字节 这种情况下,我们必须从32bit的寄存器的0地址处开始读取32bit,然后通过移位的方式得到其中的字节。 */ - #define xhci_read_cap_reg8(id, offset) (*(uint8_t *)(xhci_hc[id].vbase + offset)) #define xhci_get_ptr_cap_reg8(id, offset) ((uint8_t *)(xhci_hc[id].vbase + offset)) #define xhci_write_cap_reg8(id, offset, value) (*(uint8_t *)(xhci_hc[id].vbase + offset) = (uint8_t)value) @@ -112,15 +115,15 @@ hardware_intr_controller xhci_hc_intr_controller = * @brief 设置link TRB的命令(dword3) * */ -#define xhci_TRB_set_link_cmd(trb_vaddr) \ - do \ - { \ +#define xhci_TRB_set_link_cmd(trb_vaddr) \ + do \ + { \ struct xhci_TRB_normal_t *ptr = (struct xhci_TRB_normal_t *)(trb_vaddr); \ - ptr->TRB_type = TRB_TYPE_LINK; \ - ptr->ioc = 0; \ - ptr->chain = 0; \ - ptr->ent = 0; \ - ptr->cycle = 1; \ + ptr->TRB_type = TRB_TYPE_LINK; \ + ptr->ioc = 0; \ + ptr->chain = 0; \ + ptr->ent = 0; \ + ptr->cycle = 1; \ } while (0) // Common TRB types @@ -195,11 +198,13 @@ static int xhci_hc_stop(int id) // 判断是否已经停止 if (unlikely((xhci_read_op_reg32(id, XHCI_OPS_USBSTS) & (1 << 0)) == 1)) return 0; - + io_mfence(); xhci_write_op_reg32(id, XHCI_OPS_USBCMD, 0x00000000); + io_mfence(); char timeout = 17; while ((xhci_read_op_reg32(id, XHCI_OPS_USBSTS) & (1 << 0)) == 0) { + io_mfence(); usleep(1000); if (--timeout == 0) return -ETIMEDOUT; @@ -218,9 +223,11 @@ static int xhci_hc_reset(int id) { int retval = 0; kdebug("usbsts=%#010lx", xhci_read_op_reg32(id, XHCI_OPS_USBSTS)); + io_mfence(); // 判断HCHalted是否置位 if ((xhci_read_op_reg32(id, XHCI_OPS_USBSTS) & (1 << 0)) == 0) { + io_mfence(); kdebug("stopping usb hc..."); // 未置位,需要先尝试停止usb主机控制器 retval = xhci_hc_stop(id); @@ -230,12 +237,16 @@ static int xhci_hc_reset(int id) int timeout = 500; // wait 500ms // reset uint32_t cmd = xhci_read_op_reg32(id, XHCI_OPS_USBCMD); + io_mfence(); kdebug("cmd=%#010lx", cmd); cmd |= (1 << 1); xhci_write_op_reg32(id, XHCI_OPS_USBCMD, cmd); + io_mfence(); kdebug("after rst, sts=%#010lx", xhci_read_op_reg32(id, XHCI_OPS_USBSTS)); + io_mfence(); while (xhci_read_op_reg32(id, XHCI_OPS_USBCMD) & (1 << 1)) { + io_mfence(); usleep(1000); if (--timeout == 0) return -ETIMEDOUT; @@ -259,14 +270,15 @@ static int xhci_hc_stop_legacy(int id) // 判断当前entry是否为legacy support entry if (xhci_read_cap_reg8(id, current_offset) == XHCI_XECP_ID_LEGACY) { - + io_mfence(); // 接管控制权 xhci_write_cap_reg32(id, current_offset, xhci_read_cap_reg32(id, current_offset) | XHCI_XECP_LEGACY_OS_OWNED); - + io_mfence(); // 等待响应完成 int timeout = XHCI_XECP_LEGACY_TIMEOUT; while ((xhci_read_cap_reg32(id, current_offset) & XHCI_XECP_LEGACY_OWNING_MASK) != XHCI_XECP_LEGACY_OS_OWNED) { + io_mfence(); usleep(1000); if (--timeout == 0) { @@ -277,9 +289,10 @@ static int xhci_hc_stop_legacy(int id) // 处理完成 return 0; } - + io_mfence(); // 读取下一个entry的偏移增加量 int next_off = ((xhci_read_cap_reg32(id, current_offset) & 0xff00) >> 8) << 2; + io_mfence(); // 将指针跳转到下一个entry current_offset = next_off ? (current_offset + next_off) : 0; } while (current_offset); @@ -296,7 +309,9 @@ static int xhci_hc_stop_legacy(int id) */ static int xhci_hc_start_sched(int id) { + io_mfence(); xhci_write_op_reg32(id, XHCI_OPS_USBCMD, (1 << 0) | (1 >> 2) | (1 << 3)); + io_mfence(); usleep(100 * 1000); } @@ -308,7 +323,9 @@ static int xhci_hc_start_sched(int id) */ static int xhci_hc_stop_sched(int id) { + io_mfence(); xhci_write_op_reg32(id, XHCI_OPS_USBCMD, 0x00); + io_mfence(); } /** @@ -336,13 +353,14 @@ static uint32_t xhci_hc_get_protocol_offset(int id, uint32_t list_off, const int do { uint32_t dw0 = xhci_read_cap_reg32(id, list_off); + io_mfence(); uint32_t next_list_off = (dw0 >> 8) & 0xff; next_list_off = next_list_off ? (list_off + (next_list_off << 2)) : 0; if ((dw0 & 0xff) == XHCI_XECP_ID_PROTOCOL && ((dw0 & 0xff000000) >> 24) == version) { uint32_t dw2 = xhci_read_cap_reg32(id, list_off + 8); - + io_mfence(); if (offset != NULL) *offset = (uint32_t)(dw2 & 0xff) - 1; // 使其转换为zero based if (count != NULL) @@ -368,8 +386,9 @@ static int xhci_hc_pair_ports(int id) { struct xhci_caps_HCSPARAMS1_reg_t hcs1; + io_mfence(); memcpy(&hcs1, xhci_get_ptr_cap_reg32(id, XHCI_CAPS_HCSPARAMS1), sizeof(struct xhci_caps_HCSPARAMS1_reg_t)); - + io_mfence(); // 从hcs1获取端口数量 xhci_hc[id].port_num = hcs1.max_ports; @@ -385,15 +404,18 @@ static int xhci_hc_pair_ports(int id) // 寻找所有的usb2端口 while (next_off) { + io_mfence(); next_off = xhci_hc_get_protocol_offset(id, next_off, 2, &offset, &cnt, &protocol_flags); + io_mfence(); if (cnt) { for (int i = 0; i < cnt; ++i) { + io_mfence(); xhci_hc[id].ports[offset + i].offset = xhci_hc[id].port_num_u2++; xhci_hc[id].ports[offset + i].flags = XHCI_PROTOCOL_USB2; - + io_mfence(); // usb2 high speed only if (protocol_flags & 2) xhci_hc[id].ports[offset + i].flags |= XHCI_PROTOCOL_HSO; @@ -405,12 +427,15 @@ static int xhci_hc_pair_ports(int id) next_off = xhci_hc[id].ext_caps_off; while (next_off) { + io_mfence(); next_off = xhci_hc_get_protocol_offset(id, next_off, 3, &offset, &cnt, &protocol_flags); + io_mfence(); if (cnt) { for (int i = 0; i < cnt; ++i) { + io_mfence(); xhci_hc[id].ports[offset + i].offset = xhci_hc[id].port_num_u3++; xhci_hc[id].ports[offset + i].flags = XHCI_PROTOCOL_USB3; } @@ -424,13 +449,13 @@ static int xhci_hc_pair_ports(int id) { if (unlikely(i == j)) continue; - + io_mfence(); if ((xhci_hc[id].ports[i].offset == xhci_hc[id].ports[j].offset) && ((xhci_hc[id].ports[i].flags & XHCI_PROTOCOL_INFO) != (xhci_hc[id].ports[j].flags & XHCI_PROTOCOL_INFO))) { xhci_hc[id].ports[i].paired_port_num = j; xhci_hc[id].ports[i].flags |= XHCI_PROTOCOL_HAS_PAIR; - + io_mfence(); xhci_hc[id].ports[j].paired_port_num = i; xhci_hc[id].ports[j].flags |= XHCI_PROTOCOL_HAS_PAIR; } @@ -440,6 +465,7 @@ static int xhci_hc_pair_ports(int id) // 标记所有的usb3、单独的usb2端口为激活状态 for (int i = 0; i < xhci_hc[id].port_num; ++i) { + io_mfence(); if (XHCI_PORT_IS_USB3(id, i) || (XHCI_PORT_IS_USB2(id, i) && (!XHCI_PORT_HAS_PAIR(id, i)))) xhci_hc[id].ports[i].flags |= XHCI_PROTOCOL_ACTIVE; @@ -481,11 +507,12 @@ static uint64_t xhci_create_ring(int trbs) { int total_size = trbs * sizeof(struct xhci_TRB_t); const uint64_t vaddr = (uint64_t)kmalloc(total_size, 0); + io_mfence(); memset((void *)vaddr, 0, total_size); - + io_mfence(); // 设置最后一个trb为link trb xhci_TRB_set_link_cmd(vaddr + total_size - sizeof(struct xhci_TRB_t)); - + io_mfence(); return vaddr; } @@ -499,18 +526,19 @@ static uint64_t xhci_create_ring(int trbs) static uint64_t xhci_create_event_ring(int trbs, uint64_t *ret_ring_addr) { const uint64_t table_vaddr = (const uint64_t)kmalloc(64, 0); // table支持8个segment + io_mfence(); if (unlikely(table_vaddr == NULL)) return -ENOMEM; memset((void *)table_vaddr, 0, 64); // 暂时只创建1个segment const uint64_t seg_vaddr = (const uint64_t)kmalloc(trbs * sizeof(struct xhci_TRB_t), 0); - + io_mfence(); if (unlikely(seg_vaddr == NULL)) return -ENOMEM; memset((void *)seg_vaddr, 0, trbs * sizeof(struct xhci_TRB_t)); - + io_mfence(); // 将segment地址和大小写入table *(uint64_t *)(table_vaddr) = virt_2_phys(seg_vaddr); *(uint64_t *)(table_vaddr + 8) = trbs; @@ -522,13 +550,17 @@ static uint64_t xhci_create_event_ring(int trbs, uint64_t *ret_ring_addr) void xhci_hc_irq_enable(uint64_t irq_num) { int cid = xhci_find_hcid_by_irq_num(irq_num); + io_mfence(); if (WARN_ON(cid == -1)) return; kdebug("start msi"); + io_mfence(); pci_start_msi(xhci_hc[cid].pci_dev_hdr); kdebug("start sched"); + io_mfence(); xhci_hc_start_sched(cid); kdebug("start ports"); + io_mfence(); xhci_hc_start_ports(cid); kdebug("enabled"); } @@ -536,29 +568,34 @@ void xhci_hc_irq_enable(uint64_t irq_num) void xhci_hc_irq_disable(uint64_t irq_num) { int cid = xhci_find_hcid_by_irq_num(irq_num); + io_mfence(); if (WARN_ON(cid == -1)) return; xhci_hc_stop_sched(cid); + io_mfence(); pci_disable_msi(xhci_hc[cid].pci_dev_hdr); + io_mfence(); } uint64_t xhci_hc_irq_install(uint64_t irq_num, void *arg) { int cid = xhci_find_hcid_by_irq_num(irq_num); + io_mfence(); if (WARN_ON(cid == -1)) return -EINVAL; struct xhci_hc_irq_install_info_t *info = (struct xhci_hc_irq_install_info_t *)arg; struct msi_desc_t msi_desc; memset(&msi_desc, 0, sizeof(struct msi_desc_t)); - + io_mfence(); msi_desc.pci_dev = (struct pci_device_structure_header_t *)xhci_hc[cid].pci_dev_hdr; msi_desc.assert = info->assert; msi_desc.edge_trigger = info->edge_trigger; msi_desc.processor = info->processor; msi_desc.pci.msi_attribute.is_64 = 1; // todo: QEMU是使用msix的,因此要先在pci中实现msix + io_mfence(); int retval = pci_enable_msi(&msi_desc); kdebug("pci retval = %d", retval); kdebug("xhci irq %d installed.", irq_num); @@ -569,9 +606,11 @@ void xhci_hc_irq_uninstall(uint64_t irq_num) { // todo int cid = xhci_find_hcid_by_irq_num(irq_num); + io_mfence(); if (WARN_ON(cid == -1)) return; xhci_hc_stop(cid); + io_mfence(); } /** * @brief xhci主机控制器的中断处理函数 @@ -599,11 +638,14 @@ static int xhci_reset_port(const int id, const int port) // 相对于op寄存器基地址的偏移量 uint64_t port_status_offset = XHCI_OPS_PRS + port * 16; // kdebug("to reset %d, offset=%#018lx", port, port_status_offset); + io_mfence(); // 检查端口电源状态 if ((xhci_read_op_reg32(id, port_status_offset + XHCI_PORT_PORTSC) & (1 << 9)) == 0) { kdebug("port is power off, starting..."); + io_mfence(); xhci_write_cap_reg32(id, port_status_offset + XHCI_PORT_PORTSC, (1 << 9)); + io_mfence(); usleep(2000); // 检测端口是否被启用, 若未启用,则报错 if ((xhci_read_op_reg32(id, port_status_offset + XHCI_PORT_PORTSC) & (1 << 9)) == 0) @@ -613,10 +655,10 @@ static int xhci_reset_port(const int id, const int port) } } // kdebug("port:%d, power check ok", port); - + io_mfence(); // 确保端口的status被清0 xhci_write_op_reg32(id, port_status_offset + XHCI_PORT_PORTSC, (1 << 9) | XHCI_PORTUSB_CHANGE_BITS); - + io_mfence(); // 重置当前端口 if (XHCI_PORT_IS_USB3(id, port)) xhci_write_op_reg32(id, port_status_offset + XHCI_PORT_PORTSC, (1 << 9) | (1 << 31)); @@ -629,7 +671,9 @@ static int xhci_reset_port(const int id, const int port) int timeout = 200; while (timeout) { + io_mfence(); uint32_t val = xhci_read_op_reg32(id, port_status_offset + XHCI_PORT_PORTSC); + io_mfence(); if (XHCI_PORT_IS_USB3(id, port) && (val & (1 << 31)) == 0) break; else if (XHCI_PORT_IS_USB2(id, port) && (val & (1 << 4)) == 0) @@ -647,12 +691,14 @@ static int xhci_reset_port(const int id, const int port) // 等待恢复 usleep(USB_TIME_RST_REC * 1000); uint32_t val = xhci_read_op_reg32(id, port_status_offset + XHCI_PORT_PORTSC); - + io_mfence(); // 如果reset之后,enable bit仍然是1,那么说明reset成功 if (val & (1 << 1)) { + io_mfence(); // 清除status change bit xhci_write_op_reg32(id, port_status_offset + XHCI_PORT_PORTSC, (1 << 9) | XHCI_PORTUSB_CHANGE_BITS); + io_mfence(); } retval = 0; } @@ -691,6 +737,7 @@ static int xhci_hc_start_ports(int id) { if (XHCI_PORT_IS_USB3(id, i) && XHCI_PORT_IS_ACTIVE(id, i)) { + io_mfence(); // reset该端口 if (likely(xhci_reset_port(id, i) == 0)) // 如果端口reset成功,就获取它的描述符 // 否则,reset函数会把它给设置为未激活,并且标志配对的usb2端口是激活的 @@ -731,14 +778,18 @@ static int xhci_hc_init_intr(int id) struct xhci_caps_HCSPARAMS1_reg_t hcs1; struct xhci_caps_HCSPARAMS2_reg_t hcs2; + io_mfence(); memcpy(&hcs1, xhci_get_ptr_cap_reg32(id, XHCI_CAPS_HCSPARAMS1), sizeof(struct xhci_caps_HCSPARAMS1_reg_t)); + io_mfence(); memcpy(&hcs2, xhci_get_ptr_cap_reg32(id, XHCI_CAPS_HCSPARAMS2), sizeof(struct xhci_caps_HCSPARAMS2_reg_t)); + io_mfence(); uint32_t max_segs = (1 << (uint32_t)(hcs2.ERST_Max)); uint32_t max_interrupters = hcs1.max_intrs; // 创建 event ring retval = xhci_create_event_ring(4096, &xhci_hc[id].event_ring_vaddr); + io_mfence(); if (unlikely((int64_t)(retval) == -ENOMEM)) return -ENOMEM; xhci_hc[id].event_ring_table_vaddr = retval; @@ -747,15 +798,21 @@ static int xhci_hc_init_intr(int id) xhci_hc[id].current_event_ring_cycle = 1; // 写入第0个中断寄存器组 - xhci_write_intr_reg32(id, 0, XHCI_IR_MAN, 0x3); // 使能中断并清除pending位(这个pending位是写入1就清0的) - xhci_write_intr_reg32(id, 0, XHCI_IR_MOD, 0); // 关闭中断管制 - xhci_write_intr_reg32(id, 0, XHCI_IR_TABLE_SIZE, 1); // 当前只有1个segment + io_mfence(); + xhci_write_intr_reg32(id, 0, XHCI_IR_MAN, 0x3); // 使能中断并清除pending位(这个pending位是写入1就清0的) + io_mfence(); + xhci_write_intr_reg32(id, 0, XHCI_IR_MOD, 0); // 关闭中断管制 + io_mfence(); + xhci_write_intr_reg32(id, 0, XHCI_IR_TABLE_SIZE, 1); // 当前只有1个segment + io_mfence(); xhci_write_intr_reg64(id, 0, XHCI_IR_DEQUEUE, virt_2_phys(xhci_hc[id].event_ring_vaddr) | (1 << 3)); // 写入dequeue寄存器,并清除busy位(写1就会清除) - xhci_write_intr_reg64(id, 0, XHCI_IR_TABLE_ADDR, virt_2_phys(xhci_hc[id].event_ring_table_vaddr)); // 写入table地址 + io_mfence(); + xhci_write_intr_reg64(id, 0, XHCI_IR_TABLE_ADDR, virt_2_phys(xhci_hc[id].event_ring_table_vaddr)); // 写入table地址 + io_mfence(); // 清除状态位 xhci_write_op_reg32(id, XHCI_OPS_USBSTS, (1 << 10) | (1 << 4) | (1 << 3) | (1 << 2)); - + io_mfence(); // 开启usb中断 // 注册中断处理程序 struct xhci_hc_irq_install_info_t install_info; @@ -766,7 +823,9 @@ static int xhci_hc_init_intr(int id) char *buf = (char *)kmalloc(16, 0); memset(buf, 0, 16); sprintk(buf, "xHCI HC%d", id); + io_mfence(); irq_register(xhci_controller_irq_num[id], &install_info, &xhci_hc_irq_handler, id, &xhci_hc_intr_controller, buf); + io_mfence(); kfree(buf); kdebug("xhci host controller %d: interrupt registered. irq num=%d", id, xhci_controller_irq_num[id]); @@ -790,7 +849,7 @@ void xhci_init(struct pci_device_structure_general_device_t *dev_hdr) spin_lock(&xhci_controller_init_lock); kinfo("Initializing xhci host controller: bus=%#02x, device=%#02x, func=%#02x, VendorID=%#04x, irq_line=%d, irq_pin=%d", dev_hdr->header.bus, dev_hdr->header.device, dev_hdr->header.func, dev_hdr->header.Vendor_ID, dev_hdr->Interrupt_Line, dev_hdr->Interrupt_PIN); - + io_mfence(); int cid = xhci_hc_find_available_id(); if (cid < 0) { @@ -801,13 +860,14 @@ void xhci_init(struct pci_device_structure_general_device_t *dev_hdr) memset(&xhci_hc[cid], 0, sizeof(struct xhci_host_controller_t)); xhci_hc[cid].controller_id = cid; xhci_hc[cid].pci_dev_hdr = dev_hdr; + io_mfence(); pci_write_config(dev_hdr->header.bus, dev_hdr->header.device, dev_hdr->header.func, 0x4, 0x0006); // mem I/O access enable and bus master enable - + io_mfence(); // 为当前控制器映射寄存器地址空间 xhci_hc[cid].vbase = SPECIAL_MEMOEY_MAPPING_VIRT_ADDR_BASE + XHCI_MAPPING_OFFSET + 65536 * xhci_hc[cid].controller_id; // kdebug("dev_hdr->BAR0 & (~0xf)=%#018lx", dev_hdr->BAR0 & (~0xf)); mm_map_phys_addr(xhci_hc[cid].vbase, dev_hdr->BAR0 & (~0xf), 65536, PAGE_KERNEL_PAGE | PAGE_PWT | PAGE_PCD, true); - + io_mfence(); // 读取xhci控制寄存器 uint16_t iversion = *(uint16_t *)(xhci_hc[cid].vbase + XHCI_CAPS_HCIVERSION); @@ -824,9 +884,11 @@ void xhci_init(struct pci_device_structure_general_device_t *dev_hdr) // kdebug("hcc1.xECP=%#010lx", hcc1.xECP); // 计算operational registers的地址 xhci_hc[cid].vbase_op = xhci_hc[cid].vbase + xhci_read_cap_reg8(cid, XHCI_CAPS_CAPLENGTH); - - xhci_hc[cid].db_offset = xhci_read_cap_reg32(cid, XHCI_CAPS_DBOFF) & (~0x3); // bits [1:0] reserved + io_mfence(); + xhci_hc[cid].db_offset = xhci_read_cap_reg32(cid, XHCI_CAPS_DBOFF) & (~0x3); // bits [1:0] reserved + io_mfence(); xhci_hc[cid].rts_offset = xhci_read_cap_reg32(cid, XHCI_CAPS_RTSOFF) & (~0x1f); // bits [4:0] reserved. + io_mfence(); xhci_hc[cid].ext_caps_off = 1UL * (hcc1.xECP) * 4; xhci_hc[cid].context_size = (hcc1.csz) ? 64 : 32; @@ -845,25 +907,27 @@ void xhci_init(struct pci_device_structure_general_device_t *dev_hdr) pci_write_config(dev_hdr->header.bus, dev_hdr->header.device, dev_hdr->header.func, 0xd8, 0xffffffff); pci_write_config(dev_hdr->header.bus, dev_hdr->header.device, dev_hdr->header.func, 0xd0, 0xffffffff); } - + io_mfence(); // 关闭legacy支持 FAIL_ON_TO(xhci_hc_stop_legacy(cid), failed); - + io_mfence(); // 重置xhci控制器 FAIL_ON_TO(xhci_hc_reset(cid), failed); + io_mfence(); // 端口配对 FAIL_ON_TO(xhci_hc_pair_ports(cid), failed); + io_mfence(); // ========== 设置USB host controller ========= // 获取页面大小 kdebug("ops pgsize=%#010lx", xhci_read_op_reg32(cid, XHCI_OPS_PAGESIZE)); xhci_hc[cid].page_size = (xhci_read_op_reg32(cid, XHCI_OPS_PAGESIZE) & 0xffff) << 12; kdebug("page size=%d", xhci_hc[cid].page_size); - + io_mfence(); // 获取设备上下文空间 xhci_hc[cid].dcbaap_vaddr = (uint64_t)kmalloc(2048, 0); // 分配2KB的设备上下文地址数组空间 memset((void *)xhci_hc[cid].dcbaap_vaddr, 0, 2048); - + io_mfence(); kdebug("dcbaap_vaddr=%#018lx", xhci_hc[cid].dcbaap_vaddr); if (unlikely(!xhci_is_aligned64(xhci_hc[cid].dcbaap_vaddr))) // 地址不是按照64byte对齐 { @@ -872,7 +936,7 @@ void xhci_init(struct pci_device_structure_general_device_t *dev_hdr) } // 写入dcbaap xhci_write_op_reg64(cid, XHCI_OPS_DCBAAP, virt_2_phys(xhci_hc[cid].dcbaap_vaddr)); - + io_mfence(); // 创建command ring xhci_hc[cid].cmd_ring_vaddr = xhci_create_ring(XHCI_CMND_RING_TRBS); if (unlikely(!xhci_is_aligned64(xhci_hc[cid].cmd_ring_vaddr))) // 地址不是按照64byte对齐 @@ -883,17 +947,21 @@ void xhci_init(struct pci_device_structure_general_device_t *dev_hdr) // 设置初始cycle bit为1 xhci_hc[cid].cmd_trb_cycle = XHCI_TRB_CYCLE_ON; - + io_mfence(); // 写入command ring控制寄存器 xhci_write_op_reg64(cid, XHCI_OPS_CRCR, virt_2_phys(xhci_hc[cid].cmd_ring_vaddr) | xhci_hc[cid].cmd_trb_cycle); // 写入配置寄存器 uint32_t max_slots = hcs1.max_slots; kdebug("max slots = %d", max_slots); + io_mfence(); xhci_write_op_reg32(cid, XHCI_OPS_CONFIG, max_slots); + io_mfence(); // 写入设备通知控制寄存器 xhci_write_op_reg32(cid, XHCI_OPS_DNCTRL, (1 << 1)); // 目前只有N1被支持 + io_mfence(); FAIL_ON_TO(xhci_hc_init_intr(cid), failed_free_dyn); + io_mfence(); ++xhci_ctrl_count; spin_unlock(&xhci_controller_init_lock); return; @@ -912,13 +980,15 @@ failed_free_dyn:; // 释放动态申请的内存 kfree((void *)xhci_hc[cid].event_ring_vaddr); failed:; + io_mfence(); // 取消地址映射 mm_unmap(xhci_hc[cid].vbase, 65536); - + io_mfence(); // 清空数组 memset((void *)&xhci_hc[cid], 0, sizeof(struct xhci_host_controller_t)); failed_exceed_max:; kerror("Failed to initialize controller: bus=%d, dev=%d, func=%d", dev_hdr->header.bus, dev_hdr->header.device, dev_hdr->header.func); spin_unlock(&xhci_controller_init_lock); -} \ No newline at end of file +} +#pragma GCC pop_options \ No newline at end of file diff --git a/kernel/driver/usb/xhci/xhci.h b/kernel/driver/usb/xhci/xhci.h index 2ac11c8e..14c960f7 100644 --- a/kernel/driver/usb/xhci/xhci.h +++ b/kernel/driver/usb/xhci/xhci.h @@ -2,7 +2,7 @@ #include #include #include - +// #pragma GCC optimize("O0") #define XHCI_MAX_HOST_CONTROLLERS 4 // 本驱动程序最大支持4个xhci root hub controller #define XHCI_MAX_ROOT_HUB_PORTS 128 // 本驱动程序最大支持127个root hub 端口(第0个保留) diff --git a/kernel/exception/gate.h b/kernel/exception/gate.h index 6bdade1e..32deb002 100644 --- a/kernel/exception/gate.h +++ b/kernel/exception/gate.h @@ -12,6 +12,8 @@ #include #include +#pragma GCC push_options +#pragma GCC optimize("O0") //描述符表的结构体 struct desc_struct { @@ -184,4 +186,6 @@ void set_tss64(unsigned int *Table, unsigned long rsp0, unsigned long rsp1, unsi *(unsigned long *)(Table + 19) = ist6; *(unsigned long *)(Table + 21) = ist7; } -#endif \ No newline at end of file +#endif + +#pragma GCC pop_options \ No newline at end of file diff --git a/kernel/exception/irq.c b/kernel/exception/irq.c index f433d8f6..685249ee 100644 --- a/kernel/exception/irq.c +++ b/kernel/exception/irq.c @@ -1,7 +1,8 @@ + #include "irq.h" #include -// 对进行 + #if _INTR_8259A_ #include #else @@ -13,6 +14,8 @@ #include "gate.h" #include +#pragma GCC push_options +#pragma GCC optimize("O0") // 保存函数调用现场的寄存器 #define SAVE_ALL_REGS \ "cld; \n\t" \ @@ -254,3 +257,4 @@ void irq_init() #endif } +#pragma GCC optimize("O0") \ No newline at end of file diff --git a/kernel/exception/irq.h b/kernel/exception/irq.h index 9e172f4b..6fbfed4f 100644 --- a/kernel/exception/irq.h +++ b/kernel/exception/irq.h @@ -10,10 +10,11 @@ */ #pragma once - #include #include +#pragma GCC push_options +#pragma GCC optimize ("O0") #define IRQ_NUM 24 #define SMP_IRQ_NUM 10 @@ -165,3 +166,4 @@ int irq_unregister(ul irq_num); * @brief 初始化中断模块 */ void irq_init(); +#pragma GCC pop_options \ No newline at end of file diff --git a/kernel/main.c b/kernel/main.c index f91b1d6e..6cfb5ace 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -34,11 +34,12 @@ #include #include - +#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,12 +127,19 @@ void system_initialize() current_pcb->preempt_count = 0; // 先初始化系统调用模块 syscall_init(); + io_mfence(); // 再初始化进程模块。顺序不能调转 sched_init(); + io_mfence(); timer_init(); + // 这里必须加内存屏障,否则会出错 + io_mfence(); smp_init(); + io_mfence(); + + cpu_init(); ps2_keyboard_init(); // ps2_mouse_init(); @@ -144,20 +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(); } //操作系统内核从这里开始执行 @@ -181,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(); @@ -191,5 +204,7 @@ void Start_Kernel(void) void ignore_int() { kwarn("Unknown interrupt or fault at RIP.\n"); - while(1); -} \ No newline at end of file + while (1) + ; +} +#pragma GCC pop_options \ No newline at end of file diff --git a/kernel/mm/mm.c b/kernel/mm/mm.c index e5e15a6f..15f57652 100644 --- a/kernel/mm/mm.c +++ b/kernel/mm/mm.c @@ -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("O3") +struct memory_desc memory_management_struct = {{0}, 0}; /** * @brief 虚拟地址长度所需要的entry数量 * @@ -82,9 +85,10 @@ void mm_init() int count; multiboot2_iter(multiboot2_get_memory, mb2_mem_info, &count); - + io_mfence(); for (int i = 0; i < count; ++i) { + io_mfence(); //可用的内存 if (mb2_mem_info->type == 1) Total_Memory += mb2_mem_info->len; @@ -103,12 +107,12 @@ void mm_init() printk("[ INFO ] Total amounts of RAM : %ld bytes\n", Total_Memory); // 计算有效内存页数 - + io_mfence(); for (int i = 0; i < memory_management_struct.len_e820; ++i) { if (memory_management_struct.e820[i].type != 1) continue; - + io_mfence(); // 将内存段的起始物理地址按照2M进行对齐 ul addr_start = PAGE_2M_ALIGN(memory_management_struct.e820[i].BaseAddr); // 将内存段的终止物理地址的低2M区域清空,以实现对齐 @@ -117,7 +121,7 @@ void mm_init() // 内存段不可用 if (addr_end <= addr_start) continue; - + io_mfence(); total_2M_pages += ((addr_end - addr_start) >> PAGE_2M_SHIFT); } kinfo("Total amounts of 2M pages : %ld.", total_2M_pages); @@ -126,16 +130,18 @@ void mm_init() ul max_addr = memory_management_struct.e820[memory_management_struct.len_e820].BaseAddr + memory_management_struct.e820[memory_management_struct.len_e820].Length; // 初始化mms的bitmap // bmp的指针指向截止位置的4k对齐的上边界(防止修改了别的数据) + io_mfence(); memory_management_struct.bmp = (unsigned long *)((memory_management_struct.start_brk + PAGE_4K_SIZE - 1) & PAGE_4K_MASK); memory_management_struct.bits_size = max_addr >> PAGE_2M_SHIFT; // 物理地址空间的最大页面数 memory_management_struct.bmp_len = (((unsigned long)(max_addr >> PAGE_2M_SHIFT) + sizeof(unsigned long) * 8 - 1) / 8) & (~(sizeof(unsigned long) - 1)); // bmp由多少个unsigned long变量组成 + io_mfence(); // 初始化bitmap, 先将整个bmp空间全部置位。稍后再将可用物理内存页复位。 memset(memory_management_struct.bmp, 0xff, memory_management_struct.bmp_len); - + io_mfence(); + kdebug("1212112"); // 初始化内存页结构 // 将页结构映射于bmp之后 - memory_management_struct.pages_struct = (struct Page *)(((unsigned long)memory_management_struct.bmp + memory_management_struct.bmp_len + PAGE_4K_SIZE - 1) & PAGE_4K_MASK); memory_management_struct.count_pages = max_addr >> PAGE_2M_SHIFT; @@ -143,18 +149,25 @@ void mm_init() // 将pages_struct全部清空,以备后续初始化 memset(memory_management_struct.pages_struct, 0x00, memory_management_struct.pages_struct_len); // init pages memory + kdebug("ffff"); + io_mfence(); // 初始化内存区域 memory_management_struct.zones_struct = (struct Zone *)(((ul)memory_management_struct.pages_struct + memory_management_struct.pages_struct_len + PAGE_4K_SIZE - 1) & PAGE_4K_MASK); + io_mfence(); // 由于暂时无法计算zone结构体的数量,因此先将其设为0 memory_management_struct.count_zones = 0; + io_mfence(); // zones-struct 成员变量暂时按照5个来计算 memory_management_struct.zones_struct_len = (10 * sizeof(struct Zone) + sizeof(ul) - 1) & (~(sizeof(ul) - 1)); + io_mfence(); memset(memory_management_struct.zones_struct, 0x00, memory_management_struct.zones_struct_len); // ==== 遍历e820数组,完成成员变量初始化工作 === + kdebug("ddd"); for (int i = 0; i < memory_management_struct.len_e820; ++i) { + io_mfence(); if (memory_management_struct.e820[i].type != 1) // 不是操作系统可以使用的物理内存 continue; ul addr_start = PAGE_2M_ALIGN(memory_management_struct.e820[i].BaseAddr); @@ -200,7 +213,7 @@ void mm_init() // 初始化0~2MB的物理页 // 由于这个区间的内存由多个内存段组成,因此不会被以上代码初始化,需要我们手动配置page[0]。 - + io_mfence(); memory_management_struct.pages_struct->zone = memory_management_struct.zones_struct; memory_management_struct.pages_struct->addr_phys = 0UL; set_page_attr(memory_management_struct.pages_struct, PAGE_PGT_MAPPED | PAGE_KERNEL_INIT | PAGE_KERNEL); @@ -216,27 +229,13 @@ void mm_init() ZONE_NORMAL_INDEX = 0; ZONE_UNMAPPED_INDEX = 0; - /* - for (int i = 0; i < memory_management_struct.count_zones; ++i) - { - struct Zone *z = memory_management_struct.zones_struct + i; - // printk_color(ORANGE, BLACK, "zone_addr_start:%#18lx, zone_addr_end:%#18lx, zone_length:%#18lx, pages_group:%#18lx, count_pages:%#18lx\n", - // z->zone_addr_start, z->zone_addr_end, z->zone_length, z->pages_group, z->count_pages); - - // 1GB以上的内存空间不做映射 - // if (z->zone_addr_start >= 0x100000000 && (!ZONE_UNMAPPED_INDEX)) - // ZONE_UNMAPPED_INDEX = i; - } - */ + // kdebug("ZONE_DMA_INDEX=%d\tZONE_NORMAL_INDEX=%d\tZONE_UNMAPPED_INDEX=%d", ZONE_DMA_INDEX, ZONE_NORMAL_INDEX, ZONE_UNMAPPED_INDEX); // 设置内存页管理结构的地址,预留了一段空间,防止内存越界。 memory_management_struct.end_of_struct = (ul)((ul)memory_management_struct.zones_struct + memory_management_struct.zones_struct_len + sizeof(long) * 32) & (~(sizeof(long) - 1)); - // printk_color(ORANGE, BLACK, "code_start:%#18lx, code_end:%#18lx, data_end:%#18lx, kernel_end:%#18lx, end_of_struct:%#18lx\n", - // memory_management_struct.kernel_code_start, memory_management_struct.kernel_code_end, memory_management_struct.kernel_data_end, memory_management_struct.kernel_end, memory_management_struct.end_of_struct); - + // 初始化内存管理单元结构所占的物理页的结构体 - ul mms_max_page = (virt_2_phys(memory_management_struct.end_of_struct) >> PAGE_2M_SHIFT); // 内存管理单元所占据的序号最大的物理页 // kdebug("mms_max_page=%ld", mms_max_page); @@ -245,6 +244,7 @@ void mm_init() // 第0个page已经在上方配置 for (ul j = 1; j <= mms_max_page; ++j) { + barrier(); tmp_page = memory_management_struct.pages_struct + j; page_init(tmp_page, PAGE_PGT_MAPPED | PAGE_KERNEL | PAGE_KERNEL_INIT); page_num = tmp_page->addr_phys >> PAGE_2M_SHIFT; @@ -278,6 +278,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; @@ -976,4 +977,5 @@ int8_t mm_is_2M_page(uint64_t paddr) if(likely((paddr >> PAGE_2M_SHIFT)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 +378,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 +389,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 +411,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); diff --git a/kernel/process/process.c b/kernel/process/process.c index 077c46d6..60fe0041 100644 --- a/kernel/process/process.c +++ b/kernel/process/process.c @@ -21,6 +21,9 @@ #include +// #pragma GCC push_options +// #pragma GCC optimize("O0") + spinlock_t process_global_pid_write_lock; // 增加pid的写锁 long process_global_pid = 1; // 系统中最大的pid @@ -100,6 +103,7 @@ uint64_t process_exit_mm(struct process_control_block *pcb); uint64_t process_copy_thread(uint64_t clone_flags, struct process_control_block *pcb, uint64_t stack_start, uint64_t stack_size, struct pt_regs *current_regs); void process_exit_thread(struct process_control_block *pcb); + /** * @brief 切换进程 * @@ -108,7 +112,8 @@ void process_exit_thread(struct process_control_block *pcb); * 由于程序在进入内核的时候已经保存了寄存器,因此这里不需要保存寄存器。 * 这里切换fs和gs寄存器 */ - +#pragma GCC push_options +#pragma GCC optimize("O0") void __switch_to(struct process_control_block *prev, struct process_control_block *next) { initial_tss[proc_current_cpu_id].rsp0 = next->thread->rbp; @@ -124,6 +129,7 @@ void __switch_to(struct process_control_block *prev, struct process_control_bloc __asm__ __volatile__("movq %0, %%fs \n\t" ::"a"(next->thread->fs)); __asm__ __volatile__("movq %0, %%gs \n\t" ::"a"(next->thread->gs)); } +#pragma GCC pop_options /** * @brief 打开要执行的程序文件 @@ -299,6 +305,8 @@ load_elf_failed:; * @param envp 环境变量 * @return ul 错误码 */ +#pragma GCC push_options +#pragma GCC optimize("O0") ul do_execve(struct pt_regs *regs, char *path, char *argv[], char *envp[]) { @@ -403,6 +411,7 @@ ul do_execve(struct pt_regs *regs, char *path, char *argv[], char *envp[]) exec_failed:; process_do_exit(tmp); } +#pragma GCC pop_options /** * @brief 内核init进程 @@ -410,6 +419,8 @@ exec_failed:; * @param arg * @return ul 参数 */ +#pragma GCC push_options +#pragma GCC optimize("O0") ul initial_kernel_thread(ul arg) { // kinfo("initial proc running...\targ:%#018lx", arg); @@ -446,6 +457,7 @@ ul initial_kernel_thread(ul arg) current_pcb->thread->rip = (ul)ret_from_system_call; current_pcb->thread->rsp = (ul)current_pcb + STACK_SIZE - sizeof(struct pt_regs); current_pcb->thread->fs = USER_DS | 0x3; + barrier(); current_pcb->thread->gs = USER_DS | 0x3; // 主动放弃内核线程身份 @@ -467,7 +479,7 @@ ul initial_kernel_thread(ul arg) return 1; } - +#pragma GCC pop_options /** * @brief 当子进程退出后向父进程发送通知 * @@ -517,23 +529,29 @@ ul process_do_exit(ul code) int kernel_thread(unsigned long (*fn)(unsigned long), unsigned long arg, unsigned long flags) { struct pt_regs regs; + barrier(); memset(®s, 0, sizeof(regs)); - + barrier(); // 在rbx寄存器中保存进程的入口地址 regs.rbx = (ul)fn; // 在rdx寄存器中保存传入的参数 regs.rdx = (ul)arg; - + barrier(); regs.ds = KERNEL_DS; + barrier(); regs.es = KERNEL_DS; + barrier(); regs.cs = KERNEL_CS; + barrier(); regs.ss = KERNEL_DS; + barrier(); // 置位中断使能标志位 regs.rflags = (1 << 9); - + barrier(); // rip寄存器指向内核线程的引导程序 regs.rip = (ul)kernel_thread_func; + barrier(); // kdebug("kernel_thread_func=%#018lx", kernel_thread_func); // kdebug("&kernel_thread_func=%#018lx", &kernel_thread_func); // kdebug("1111\tregs.rip = %#018lx", regs.rip); @@ -577,23 +595,34 @@ void process_init() for (int i = 256; i < 512; ++i) { uint64_t *tmp = idle_pml4t_vaddr + i; + barrier(); if (*tmp == 0) { void *pdpt = kmalloc(PAGE_4K_SIZE, 0); + barrier(); memset(pdpt, 0, PAGE_4K_SIZE); + barrier(); set_pml4t(tmp, mk_pml4t(virt_2_phys(pdpt), PAGE_KERNEL_PGT)); } } + barrier(); + + flush_tlb(); /* kdebug("initial_thread.rbp=%#018lx", initial_thread.rbp); kdebug("initial_tss[0].rsp1=%#018lx", initial_tss[0].rsp1); kdebug("initial_tss[0].ist1=%#018lx", initial_tss[0].ist1); */ // 初始化pid的写锁 + spin_init(&process_global_pid_write_lock); + // 初始化进程的循环链表 list_init(&initial_proc_union.pcb.list); + barrier(); kernel_thread(initial_kernel_thread, 10, CLONE_FS | CLONE_SIGNAL); // 初始化内核线程 + barrier(); + initial_proc_union.pcb.state = PROC_RUNNING; initial_proc_union.pcb.preempt_count = 0; initial_proc_union.pcb.cpu_id = 0; @@ -617,6 +646,7 @@ unsigned long do_fork(struct pt_regs *regs, unsigned long clone_flags, unsigned // 为新的进程分配栈空间,并将pcb放置在底部 tsk = (struct process_control_block *)kmalloc(STACK_SIZE, 0); + barrier(); if (tsk == NULL) { @@ -624,13 +654,17 @@ unsigned long do_fork(struct pt_regs *regs, unsigned long clone_flags, unsigned return retval; } + barrier(); memset(tsk, 0, sizeof(struct process_control_block)); + io_mfence(); // 将当前进程的pcb复制到新的pcb内 memcpy(tsk, current_pcb, sizeof(struct process_control_block)); + io_mfence(); // 初始化进程的循环链表结点 list_init(&tsk->list); + io_mfence(); // 判断是否为内核态调用fork if (current_pcb->flags & PF_KTHREAD && stack_start != 0) tsk->flags |= PF_KFORK; @@ -641,11 +675,14 @@ unsigned long do_fork(struct pt_regs *regs, unsigned long clone_flags, unsigned // 增加全局的pid并赋值给新进程的pid spin_lock(&process_global_pid_write_lock); tsk->pid = process_global_pid++; - + barrier(); // 加入到进程链表中 tsk->next_pcb = initial_proc_union.pcb.next_pcb; + barrier(); initial_proc_union.pcb.next_pcb = tsk; + barrier(); tsk->parent_pcb = current_pcb; + barrier(); spin_unlock(&process_global_pid_write_lock); @@ -654,7 +691,7 @@ unsigned long do_fork(struct pt_regs *regs, unsigned long clone_flags, unsigned tsk->parent_pcb = current_pcb; wait_queue_init(&tsk->wait_child_proc_exit, NULL); - + barrier(); list_init(&tsk->list); retval = -ENOMEM; @@ -1047,6 +1084,7 @@ uint64_t process_copy_thread(uint64_t clone_flags, struct process_control_block child_regs = (struct pt_regs *)(((uint64_t)pcb) + STACK_SIZE - size); memcpy(child_regs, (void *)current_regs, size); + barrier(); // 然后重写新的栈中,每个栈帧的rbp值 process_rewrite_rbp(child_regs, pcb); } @@ -1054,6 +1092,7 @@ uint64_t process_copy_thread(uint64_t clone_flags, struct process_control_block { child_regs = (struct pt_regs *)((uint64_t)pcb + STACK_SIZE - sizeof(struct pt_regs)); memcpy(child_regs, current_regs, sizeof(struct pt_regs)); + barrier(); child_regs->rsp = stack_start; } @@ -1087,4 +1126,6 @@ uint64_t process_copy_thread(uint64_t clone_flags, struct process_control_block */ void process_exit_thread(struct process_control_block *pcb) { -} \ No newline at end of file +} + +// #pragma GCC pop_options \ No newline at end of file diff --git a/kernel/process/process.h b/kernel/process/process.h index d1c7b28a..f1e2acb9 100644 --- a/kernel/process/process.h +++ b/kernel/process/process.h @@ -9,7 +9,6 @@ */ #pragma once - #include #include #include @@ -19,6 +18,8 @@ #include #include + + // 进程最大可拥有的文件描述符数量 #define PROC_MAX_FD_NUM 16 @@ -213,17 +214,21 @@ struct tss_struct .io_map_base_addr = 0 \ } +#pragma GCC push_options +#pragma GCC optimize("O0") // 获取当前的pcb struct process_control_block *get_current_pcb() { struct process_control_block *current = NULL; // 利用了当前pcb和栈空间总大小为32k大小对齐,将rsp低15位清空,即可获得pcb的起始地址 + barrier(); __asm__ __volatile__("andq %%rsp, %0 \n\t" : "=r"(current) : "0"(~32767UL)); + barrier(); return current; }; - +#pragma GCC pop_options #define current_pcb get_current_pcb() #define GET_CURRENT_PCB \ @@ -350,7 +355,7 @@ int kernel_thread(unsigned long (*fn)(unsigned long), unsigned long arg, unsigne asm volatile("movq %0, %%cr3 \n\t" ::"r"(next_pcb->mm->pgd) \ : "memory"); \ } while (0) -// flush_tlb(); \ +// flush_tlb(); // 获取当前cpu id #define proc_current_cpu_id (current_pcb->cpu_id) diff --git a/kernel/sched/sched.c b/kernel/sched/sched.c index 5d94c751..ce28b508 100644 --- a/kernel/sched/sched.c +++ b/kernel/sched/sched.c @@ -3,6 +3,7 @@ #include #include + struct sched_queue_t sched_cfs_ready_queue[MAX_CPU_NUM]; // 就绪队列 /** diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index 1a109f34..371ba820 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -45,4 +45,5 @@ void sched_init(); * @brief 当时钟中断到达时,更新时间片 * */ -void sched_update_jiffies(); \ No newline at end of file +void sched_update_jiffies(); + diff --git a/kernel/smp/smp.c b/kernel/smp/smp.c index 1e346088..e9068730 100644 --- a/kernel/smp/smp.c +++ b/kernel/smp/smp.c @@ -30,43 +30,51 @@ void smp_init() // kdebug("processor num=%d", total_processor_num); for (int i = 0; i < total_processor_num; ++i) + { + io_mfence(); proc_local_apic_structs[i] = (struct acpi_Processor_Local_APIC_Structure_t *)(tmp_vaddr[i]); + } //*(uchar *)0x20000 = 0xf4; // 在内存的0x20000处写入HLT指令(AP处理器会执行物理地址0x20000的代码) // 将引导程序复制到物理地址0x20000处 memcpy((unsigned char *)phys_2_virt(0x20000), _apu_boot_start, (unsigned long)&_apu_boot_end - (unsigned long)&_apu_boot_start); - + io_mfence(); // 设置多核IPI中断门 for (int i = 200; i < 210; ++i) set_intr_gate(i, 0, SMP_interrupt_table[i - 200]); - memset((void *)SMP_IPI_desc, 0, sizeof(irq_desc_t) * SMP_IRQ_NUM); + + io_mfence(); // 注册接收bsp处理器的hpet中断转发的处理函数 ipi_regiserIPI(0xc8, NULL, &ipi_0xc8_handler, NULL, NULL, "IPI 0xc8"); - + io_mfence(); ipi_send_IPI(DEST_PHYSICAL, IDLE, ICR_LEVEL_DE_ASSERT, EDGE_TRIGGER, 0x00, ICR_INIT, ICR_ALL_EXCLUDE_Self, true, 0x00); 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; + io_mfence(); if (proc_local_apic_structs[i]->local_apic_id > total_processor_num) - { - --total_processor_num; - continue;} + { + --total_processor_num; + 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); - + io_mfence(); spin_lock(&multi_core_starting_lock); - preempt_enable(); // 由于ap处理器的pcb与bsp的不同,因此ap处理器放锁时,bsp的自旋锁持有计数不会发生改变,需要手动恢复preempt count + preempt_enable(); // 由于ap处理器的pcb与bsp的不同,因此ap处理器放锁时,bsp的自旋锁持有计数不会发生改变,需要手动恢复preempt count current_starting_cpu = proc_local_apic_structs[i]->local_apic_id; - - + io_mfence(); // 为每个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; + io_mfence(); memset((void *)cpu_core_info[current_starting_cpu].stack_start - STACK_SIZE, 0, STACK_SIZE); memset((void *)cpu_core_info[current_starting_cpu].ist_stack_start - STACK_SIZE, 0, STACK_SIZE); + io_mfence(); // 设置ap处理器的中断栈及内核栈中的cpu_id ((struct process_control_block *)(cpu_core_info[current_starting_cpu].stack_start - STACK_SIZE))->cpu_id = proc_local_apic_structs[i]->local_apic_id; @@ -77,18 +85,18 @@ 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); - + io_mfence(); // 连续发送两次start-up IPI ipi_send_IPI(DEST_PHYSICAL, IDLE, ICR_LEVEL_DE_ASSERT, EDGE_TRIGGER, 0x20, ICR_Start_up, ICR_No_Shorthand, true, proc_local_apic_structs[i]->local_apic_id); + io_mfence(); ipi_send_IPI(DEST_PHYSICAL, IDLE, ICR_LEVEL_DE_ASSERT, EDGE_TRIGGER, 0x20, ICR_Start_up, ICR_No_Shorthand, true, proc_local_apic_structs[i]->local_apic_id); } - + io_mfence(); while (num_cpu_started != total_processor_num) - __asm__ __volatile__("pause" :: - : "memory"); + pause(); kinfo("Cleaning page table remapping...\n"); @@ -96,6 +104,7 @@ void smp_init() uint64_t *global_CR3 = get_CR3(); for (int i = 0; i < 256; ++i) { + io_mfence(); *(ul *)(phys_2_virt(global_CR3) + i) = 0UL; } kdebug("init proc's preempt_count=%ld", current_pcb->preempt_count); @@ -121,7 +130,7 @@ void smp_ap_start() __asm__ __volatile__("movq %0, %%rsp \n\t" ::"m"(stack_start) : "memory");*/ ksuccess("AP core successfully started!"); - + io_mfence(); ++num_cpu_started; kdebug("current cpu = %d", current_starting_cpu); @@ -154,7 +163,8 @@ void smp_ap_start() // kdebug("IDT_addr = %#018lx", phys_2_virt(IDT_Table)); spin_unlock(&multi_core_starting_lock); - preempt_disable();// 由于ap处理器的pcb与bsp的不同,因此ap处理器放锁时,需要手动恢复preempt count + preempt_disable(); // 由于ap处理器的pcb与bsp的不同,因此ap处理器放锁时,需要手动恢复preempt count + io_mfence(); sti(); while (1) @@ -176,4 +186,4 @@ void smp_ap_start() void ipi_0xc8_handler(uint64_t irq_num, uint64_t param, struct pt_regs *regs) { sched_update_jiffies(); -} \ No newline at end of file +} diff --git a/kernel/syscall/syscall.c b/kernel/syscall/syscall.c index af5bbe63..bb6e25a1 100644 --- a/kernel/syscall/syscall.c +++ b/kernel/syscall/syscall.c @@ -22,9 +22,18 @@ extern uint64_t sys_clock(struct pt_regs *regs); * @brief 导出系统调用处理函数的符号 * */ -#define SYSCALL_COMMON(syscall_num, symbol) extern unsigned long symbol(struct pt_regs *regs); -SYSCALL_COMMON(0, system_call_not_exists); // 导出system_call_not_exists函数 -#undef SYSCALL_COMMON // 取消前述宏定义 + +/** + * @brief 系统调用不存在时的处理函数 + * + * @param regs 进程3特权级下的寄存器 + * @return ul + */ +ul system_call_not_exists(struct pt_regs *regs) +{ + kerror("System call [ ID #%d ] not exists.", regs->rax); + return ESYSCALL_NOT_EXISTS; +} // 取消前述宏定义 /** * @brief 重新定义为:把系统调用函数加入系统调用表 diff --git a/kernel/syscall/syscall.h b/kernel/syscall/syscall.h index e6436c77..419f0572 100644 --- a/kernel/syscall/syscall.h +++ b/kernel/syscall/syscall.h @@ -36,11 +36,7 @@ long enter_syscall_int(ul syscall_id, ul arg0, ul arg1, ul arg2, ul arg3, ul arg * @param regs 进程3特权级下的寄存器 * @return ul */ -ul system_call_not_exists(struct pt_regs *regs) -{ - kerror("System call [ ID #%d ] not exists.", regs->rax); - return ESYSCALL_NOT_EXISTS; -} +ul system_call_not_exists(struct pt_regs *regs); /** * @brief 打印字符串的系统调用 diff --git a/tools/batch_delete_loop.py b/tools/batch_delete_loop.py new file mode 100644 index 00000000..23b5015a --- /dev/null +++ b/tools/batch_delete_loop.py @@ -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!") \ No newline at end of file