mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-09 15:26:47 +00:00
Merge branch 'master' into patch-usb-hid-parse
This commit is contained in:
commit
f5be8074dc
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@ -146,7 +146,8 @@
|
||||
"lockref.h": "c",
|
||||
"compiler_attributes.h": "c",
|
||||
"timer.h": "c",
|
||||
"hid.h": "c"
|
||||
"hid.h": "c",
|
||||
"cfs.h": "c"
|
||||
},
|
||||
"C_Cpp.errorSquiggles": "Enabled",
|
||||
"esbonio.sphinx.confDir": ""
|
||||
|
1
Makefile
1
Makefile
@ -16,6 +16,7 @@ ifeq ($(DEBUG), DEBUG)
|
||||
GLOBAL_CFLAGS += -g
|
||||
endif
|
||||
|
||||
export CC=gcc
|
||||
|
||||
.PHONY: all
|
||||
all: kernel user
|
||||
|
@ -22,14 +22,14 @@ kernel_subdirs := common driver process debug filesystem time arch exception mm
|
||||
|
||||
|
||||
head.o: head.S
|
||||
gcc -E head.S > _head.s # 预处理
|
||||
$(CC) -E head.S > _head.s # 预处理
|
||||
as $(ASFLAGS) -o head.o _head.s
|
||||
|
||||
|
||||
main.o: main.c
|
||||
# -fno-builtin: 不使用C语言内建函数
|
||||
# The -m64 option sets int to 32bits and long and pointer to 64 bits and generates code for AMD’s x86-64 architecture.
|
||||
gcc $(CFLAGS) -c main.c -o main.o
|
||||
$(CC) $(CFLAGS) -c main.c -o main.o
|
||||
|
||||
|
||||
all: kernel
|
||||
|
@ -3,8 +3,8 @@ CFLAGS += -I .
|
||||
all: x86_64_ipi.o ia64_msi.o
|
||||
|
||||
x86_64_ipi.o: x86_64_ipi.c
|
||||
gcc $(CFLAGS) -c x86_64_ipi.c -o x86_64_ipi.o
|
||||
$(CC) $(CFLAGS) -c x86_64_ipi.c -o x86_64_ipi.o
|
||||
|
||||
ia64_msi.o: ia64_msi.c
|
||||
gcc $(CFLAGS) -c ia64_msi.c -o ia64_msi.o
|
||||
$(CC) $(CFLAGS) -c ia64_msi.c -o ia64_msi.o
|
||||
|
||||
|
@ -78,4 +78,4 @@ extern void __cmpxchg_wrong_size(void) __compiletime_error("Bad argument size fo
|
||||
})
|
||||
|
||||
#define arch_try_cmpxchg(ptr, old_ptr, new_ptr) \
|
||||
__raw_try_cmpxchg((ptr), (old_ptr), (new_ptr), sizeof(*ptr))
|
||||
__raw_try_cmpxchg((ptr), (old_ptr), (new_ptr), sizeof(*ptr))
|
||||
|
@ -77,7 +77,9 @@ struct hid_parser
|
||||
int usage_max;
|
||||
|
||||
int cnt_objects; // report descriptor中的对象数目
|
||||
int cnt_report // report desc中的report数目
|
||||
|
||||
int cnt_report; // report desc中的report数目
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <common/spinlock.h>
|
||||
|
||||
struct kfifo_t
|
||||
{
|
||||
@ -73,10 +74,10 @@ int kfifo_alloc(struct kfifo_t *fifo, uint32_t size, uint64_t reserved);
|
||||
|
||||
/**
|
||||
* @brief 释放通过kfifo_alloc创建的fifo缓冲区
|
||||
*
|
||||
*
|
||||
* @param fifo fifo队列结构体
|
||||
*/
|
||||
void kfifo_free_alloc(struct kfifo_t* fifo);
|
||||
void kfifo_free_alloc(struct kfifo_t *fifo);
|
||||
|
||||
/**
|
||||
* @brief 使用指定的缓冲区来初始化kfifo缓冲队列
|
||||
@ -116,3 +117,37 @@ uint32_t kfifo_out(struct kfifo_t *fifo, void *to, uint32_t size);
|
||||
* @return uint32_t 取出的数据大小
|
||||
*/
|
||||
uint32_t kfifo_out_peek(struct kfifo_t *fifo, void *to, uint32_t size);
|
||||
|
||||
/**
|
||||
* @brief 向kfifo缓冲区推入指定大小的数据并在过程加锁
|
||||
*
|
||||
* @param fifo 队列结构体
|
||||
* @param from 来源数据地址
|
||||
* @param size 数据大小(字节数)
|
||||
* @param lock 自旋锁
|
||||
* @return uint32_t 推入的数据大小
|
||||
*/
|
||||
uint32_t __always_inline kfifo_in_locked(struct kfifo_t *fifo, const void *from, uint32_t size, spinlock_t *lock)
|
||||
{
|
||||
spin_lock(lock);
|
||||
uint32_t retval = kfifo_in(fifo, from, size);
|
||||
spin_unlock(lock);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 从kfifo缓冲区取出数据,并从队列中删除数据,并在过程加锁
|
||||
*
|
||||
* @param fifo 队列结构体
|
||||
* @param to 拷贝目标地址
|
||||
* @param size 数据大小(字节数)
|
||||
* @param lock 自旋锁
|
||||
* @return uint32_t 取出的数据大小
|
||||
*/
|
||||
uint32_t __always_inline kfifo_out_locked(struct kfifo_t *fifo, void *to, uint32_t size, spinlock_t *lock)
|
||||
{
|
||||
spin_lock(lock);
|
||||
uint32_t retval = kfifo_out(fifo, to, size);
|
||||
spin_unlock(lock);
|
||||
return retval;
|
||||
}
|
||||
|
@ -5,10 +5,10 @@ CFLAGS += -I .
|
||||
all: fabs.o round.o pow.o
|
||||
|
||||
fabs.o: fabs.c
|
||||
gcc $(CFLAGS) -c fabs.c -o fabs.o
|
||||
$(CC) $(CFLAGS) -c fabs.c -o fabs.o
|
||||
|
||||
round.o: round.c
|
||||
gcc $(CFLAGS) -c round.c -o round.o
|
||||
$(CC) $(CFLAGS) -c round.c -o round.o
|
||||
|
||||
pow.o: pow.c
|
||||
gcc $(CFLAGS) -c pow.c -o pow.o
|
||||
$(CC) $(CFLAGS) -c pow.c -o pow.o
|
@ -4,11 +4,11 @@ all: traceback.o
|
||||
CFLAGS += -I .
|
||||
|
||||
kallsyms.o: kallsyms.c
|
||||
gcc -o kallsyms kallsyms.c
|
||||
$(CC) -o kallsyms kallsyms.c
|
||||
rm -rf kallsyms.o
|
||||
|
||||
traceback.o: traceback/traceback.c
|
||||
gcc $(CFLAGS) -c traceback/traceback.c -o traceback/traceback.o
|
||||
$(CC) $(CFLAGS) -c traceback/traceback.c -o traceback/traceback.o
|
||||
|
||||
|
||||
# 生成内核栈符号表的汇编文件
|
||||
@ -16,7 +16,7 @@ generate_kallsyms: kallsyms.o
|
||||
echo "Generating kallsyms..."
|
||||
|
||||
nm -n $(kernel_root_path)/kernel | ./kallsyms > kallsyms.S
|
||||
gcc -c kallsyms.S -o kallsyms.o
|
||||
$(CC) -c kallsyms.S -o kallsyms.o
|
||||
@echo "Kallsyms generated."
|
||||
|
||||
|
||||
|
@ -5,4 +5,4 @@ CFLAGS += -I .
|
||||
|
||||
|
||||
acpi.o: acpi.c
|
||||
gcc $(CFLAGS) -c acpi.c -o acpi.o
|
||||
$(CC) $(CFLAGS) -c acpi.c -o acpi.o
|
||||
|
@ -4,7 +4,7 @@ all: ata.o ahci.o
|
||||
CFLAGS += -I .
|
||||
|
||||
ata.o: ata.c
|
||||
gcc $(CFLAGS) -c ata.c -o ata.o
|
||||
$(CC) $(CFLAGS) -c ata.c -o ata.o
|
||||
|
||||
ahci.o: ahci/ahci.c
|
||||
gcc $(CFLAGS) -c ahci/ahci.c -o ahci/ahci.o
|
||||
$(CC) $(CFLAGS) -c ahci/ahci.c -o ahci/ahci.o
|
@ -12,7 +12,7 @@ $(kernel_driver_hid_subdirs): ECHO
|
||||
$(MAKE) -C $@ all CFLAGS="$(CFLAGS)" ASFLAGS="$(ASFLAGS)" PIC="$(PIC)"
|
||||
|
||||
$(kernel_driver_hid_objs): ECHO
|
||||
gcc $(CFLAGS) -c $@ -o $@.o
|
||||
$(CC) $(CFLAGS) -c $@ -o $@.o
|
||||
|
||||
all: $(kernel_driver_hid_objs) $(kernel_driver_hid_subdirs)
|
||||
@echo $(kernel_driver_hid_objs)
|
||||
|
@ -8,7 +8,7 @@ ECHO:
|
||||
@echo "$@"
|
||||
|
||||
$(kernel_driver_usbhid_objs): ECHO
|
||||
gcc $(CFLAGS) -c $@ -o $@.o
|
||||
$(CC) $(CFLAGS) -c $@ -o $@.o
|
||||
|
||||
all: $(kernel_driver_hid_objs) $(kernel_driver_hid_subdirs)
|
||||
@echo $(kernel_driver_hid_objs)
|
||||
|
@ -4,11 +4,11 @@ all: pic.o
|
||||
# 中断处理芯片的驱动程序
|
||||
ifeq ($(PIC), _INTR_8259A_)
|
||||
pic.o: 8259A/8259A.c
|
||||
gcc $(CFLAGS) -c 8259A/8259A.c -o pic.o
|
||||
$(CC) $(CFLAGS) -c 8259A/8259A.c -o pic.o
|
||||
else
|
||||
pic.o: apic/apic.c apic_timer.o
|
||||
gcc $(CFLAGS) -c apic/apic.c -o pic.o
|
||||
$(CC) $(CFLAGS) -c apic/apic.c -o pic.o
|
||||
|
||||
apic_timer.o: apic/apic_timer.c
|
||||
gcc $(CFLAGS) -c apic/apic_timer.c -o apic/apic_timer.o
|
||||
$(CC) $(CFLAGS) -c apic/apic_timer.c -o apic/apic_timer.o
|
||||
endif
|
@ -344,7 +344,7 @@ void apic_local_apic_init()
|
||||
* @brief 初始化apic控制器
|
||||
*
|
||||
*/
|
||||
void apic_init()
|
||||
int apic_init()
|
||||
{
|
||||
// 初始化中断门, 中断使用rsp0防止在软中断时发生嵌套,然后处理器重新加载导致数据被抹掉
|
||||
for (int i = 32; i <= 55; ++i)
|
||||
@ -386,6 +386,7 @@ void apic_init()
|
||||
kwarn("Cannot get RCBA address. RCBA_phys=%#010lx", RCBA_phys);
|
||||
}
|
||||
sti();
|
||||
return 0;
|
||||
}
|
||||
/**
|
||||
* @brief 中断服务程序
|
||||
|
@ -290,7 +290,7 @@ void apic_init_ap_core_local_apic();
|
||||
* @brief 初始化apic控制器
|
||||
*
|
||||
*/
|
||||
void apic_init();
|
||||
int apic_init();
|
||||
|
||||
/**
|
||||
* @brief 读取指定类型的 Interrupt Control Structure
|
||||
|
@ -5,4 +5,4 @@ CFLAGS += -I .
|
||||
|
||||
|
||||
ps2_keyboard.o: ps2_keyboard.c
|
||||
gcc $(CFLAGS) -c ps2_keyboard.c -o ps2_keyboard.o
|
||||
$(CC) $(CFLAGS) -c ps2_keyboard.c -o ps2_keyboard.o
|
@ -5,4 +5,4 @@ CFLAGS += -I .
|
||||
|
||||
|
||||
ps2_mouse.o: ps2_mouse.c
|
||||
gcc $(CFLAGS) -c ps2_mouse.c -o ps2_mouse.o
|
||||
$(CC) $(CFLAGS) -c ps2_mouse.c -o ps2_mouse.o
|
@ -4,4 +4,4 @@ all: multiboot2.o
|
||||
CFLAGS += -I .
|
||||
|
||||
multiboot2.o: multiboot2.c
|
||||
gcc $(CFLAGS) -c multiboot2.c -o multiboot2.o
|
||||
$(CC) $(CFLAGS) -c multiboot2.c -o multiboot2.o
|
@ -5,7 +5,7 @@ CFLAGS += -I .
|
||||
|
||||
|
||||
pci.o: pci.c
|
||||
gcc $(CFLAGS) -c pci.c -o pci.o
|
||||
$(CC) $(CFLAGS) -c pci.c -o pci.o
|
||||
|
||||
msi.o: msi.c
|
||||
gcc $(CFLAGS) -c msi.c -o msi.o
|
||||
$(CC) $(CFLAGS) -c msi.c -o msi.o
|
||||
|
@ -4,7 +4,7 @@ all: rtc.o HPET.o
|
||||
CFLAGS += -I .
|
||||
|
||||
rtc.o: rtc/rtc.c
|
||||
gcc $(CFLAGS) -c rtc/rtc.c -o rtc/rtc.o
|
||||
$(CC) $(CFLAGS) -c rtc/rtc.c -o rtc/rtc.o
|
||||
|
||||
HPET.o: HPET/HPET.c
|
||||
gcc $(CFLAGS) -c HPET/HPET.c -o HPET/HPET.o
|
||||
$(CC) $(CFLAGS) -c HPET/HPET.c -o HPET/HPET.o
|
||||
|
@ -5,4 +5,4 @@ CFLAGS += -I .
|
||||
|
||||
|
||||
tty.o: tty.c
|
||||
gcc $(CFLAGS) -c tty.c -o tty.o
|
||||
$(CC) $(CFLAGS) -c tty.c -o tty.o
|
@ -4,4 +4,4 @@ all: uart.o
|
||||
CFLAGS += -I .
|
||||
|
||||
uart.o: uart.c
|
||||
gcc $(CFLAGS) -c uart.c -o uart.o
|
||||
$(CC) $(CFLAGS) -c uart.c -o uart.o
|
||||
|
@ -3,7 +3,7 @@ CFLAGS += -I .
|
||||
all: usb.o xhci.o
|
||||
|
||||
usb.o: usb.c
|
||||
gcc $(CFLAGS) -c usb.c -o usb.o
|
||||
$(CC) $(CFLAGS) -c usb.c -o usb.o
|
||||
|
||||
xhci.o: xhci/xhci.c
|
||||
gcc $(CFLAGS) -c xhci/xhci.c -o xhci/xhci.o
|
||||
$(CC) $(CFLAGS) -c xhci/xhci.c -o xhci/xhci.o
|
@ -5,4 +5,4 @@ CFLAGS += -I .
|
||||
|
||||
|
||||
video.o: video.c
|
||||
gcc $(CFLAGS) -c video.c -o video.o
|
||||
$(CC) $(CFLAGS) -c video.c -o video.o
|
||||
|
@ -5,14 +5,14 @@ CFLAGS += -I .
|
||||
all: entry.o irq.o softirq.o trap.o
|
||||
|
||||
entry.o: entry.S
|
||||
gcc -E entry.S > _entry.s
|
||||
$(CC) -E entry.S > _entry.s
|
||||
as $(ASFLAGS) -o entry.o _entry.s
|
||||
|
||||
trap.o: trap.c
|
||||
gcc $(CFLAGS) -c trap.c -o trap.o
|
||||
$(CC) $(CFLAGS) -c trap.c -o trap.o
|
||||
|
||||
softirq.o: softirq.c
|
||||
gcc $(CFLAGS) -c softirq.c -o softirq.o
|
||||
$(CC) $(CFLAGS) -c softirq.c -o softirq.o
|
||||
|
||||
irq.o: irq.c
|
||||
gcc $(CFLAGS) -c irq.c -o irq.o
|
||||
$(CC) $(CFLAGS) -c irq.c -o irq.o
|
@ -351,4 +351,11 @@ ENTRY(syscall_int)
|
||||
xchgq %rax, (%rsp) // 把FUNC的地址换入栈中
|
||||
jmp Err_Code
|
||||
|
||||
// irq模块初始化后的ignore_int入点
|
||||
ENTRY(ignore_int)
|
||||
pushq $0
|
||||
pushq %rax
|
||||
leaq ignore_int_handler(%rip), %rax // 获取ignore处理程序的地址
|
||||
xchgq %rax, (%rsp) // 把FUNC的地址换入栈中
|
||||
jmp Err_Code
|
||||
|
||||
|
@ -2,47 +2,47 @@
|
||||
#include "irq.h"
|
||||
#include <common/errno.h>
|
||||
|
||||
|
||||
#if _INTR_8259A_
|
||||
#include <driver/interrupt/8259A/8259A.h>
|
||||
#else
|
||||
#include <driver/interrupt/apic/apic.h>
|
||||
#endif
|
||||
|
||||
#include "gate.h"
|
||||
#include <common/asm.h>
|
||||
#include <common/printk.h>
|
||||
#include <common/string.h>
|
||||
#include "gate.h"
|
||||
#include <mm/slab.h>
|
||||
extern void ignore_int();
|
||||
|
||||
#pragma GCC push_options
|
||||
#pragma GCC optimize("O0")
|
||||
// 保存函数调用现场的寄存器
|
||||
#define SAVE_ALL_REGS \
|
||||
"cld; \n\t" \
|
||||
"pushq %rax; \n\t" \
|
||||
"pushq %rax; \n\t" \
|
||||
"movq %es, %rax; \n\t" \
|
||||
"pushq %rax; \n\t" \
|
||||
"movq %ds, %rax; \n\t" \
|
||||
"pushq %rax; \n\t" \
|
||||
"xorq %rax, %rax;\n\t" \
|
||||
"pushq %rbp; \n\t" \
|
||||
"pushq %rdi; \n\t" \
|
||||
"pushq %rsi; \n\t" \
|
||||
"pushq %rdx; \n\t" \
|
||||
"pushq %rcx; \n\t" \
|
||||
"pushq %rbx; \n\t" \
|
||||
"pushq %r8 ; \n\t" \
|
||||
"pushq %r9 ; \n\t" \
|
||||
"pushq %r10; \n\t" \
|
||||
"pushq %r11; \n\t" \
|
||||
"pushq %r12; \n\t" \
|
||||
"pushq %r13; \n\t" \
|
||||
"pushq %r14; \n\t" \
|
||||
"pushq %r15; \n\t" \
|
||||
"movq $0x10, %rdx;\n\t" \
|
||||
"movq %rdx, %ds; \n\t" \
|
||||
#define SAVE_ALL_REGS \
|
||||
"cld; \n\t" \
|
||||
"pushq %rax; \n\t" \
|
||||
"pushq %rax; \n\t" \
|
||||
"movq %es, %rax; \n\t" \
|
||||
"pushq %rax; \n\t" \
|
||||
"movq %ds, %rax; \n\t" \
|
||||
"pushq %rax; \n\t" \
|
||||
"xorq %rax, %rax;\n\t" \
|
||||
"pushq %rbp; \n\t" \
|
||||
"pushq %rdi; \n\t" \
|
||||
"pushq %rsi; \n\t" \
|
||||
"pushq %rdx; \n\t" \
|
||||
"pushq %rcx; \n\t" \
|
||||
"pushq %rbx; \n\t" \
|
||||
"pushq %r8 ; \n\t" \
|
||||
"pushq %r9 ; \n\t" \
|
||||
"pushq %r10; \n\t" \
|
||||
"pushq %r11; \n\t" \
|
||||
"pushq %r12; \n\t" \
|
||||
"pushq %r13; \n\t" \
|
||||
"pushq %r14; \n\t" \
|
||||
"pushq %r15; \n\t" \
|
||||
"movq $0x10, %rdx;\n\t" \
|
||||
"movq %rdx, %ds; \n\t" \
|
||||
"movq %rdx, %es; \n\t"
|
||||
|
||||
// 定义IRQ处理函数的名字格式:IRQ+中断号+interrupt
|
||||
@ -52,14 +52,13 @@
|
||||
// 构造中断entry
|
||||
// 为了复用返回函数的代码,需要压入一个错误码0
|
||||
// todo: 将这里改为volatile,也许能解决编译选项为O1时,系统崩溃的问题
|
||||
#define Build_IRQ(number) \
|
||||
void IRQ_NAME(number); \
|
||||
__asm__(SYMBOL_NAME_STR(IRQ) #number "interrupt: \n\t" \
|
||||
"pushq $0x00 \n\t" SAVE_ALL_REGS \
|
||||
"movq %rsp, %rdi \n\t" \
|
||||
"leaq ret_from_intr(%rip), %rax \n\t" \
|
||||
"pushq %rax \n\t" \
|
||||
"movq $" #number ", %rsi \n\t" \
|
||||
#define Build_IRQ(number) \
|
||||
void IRQ_NAME(number); \
|
||||
__asm__(SYMBOL_NAME_STR(IRQ) #number "interrupt: \n\t" \
|
||||
"pushq $0x00 \n\t" SAVE_ALL_REGS "movq %rsp, %rdi \n\t" \
|
||||
"leaq ret_from_intr(%rip), %rax \n\t" \
|
||||
"pushq %rax \n\t" \
|
||||
"movq $" #number ", %rsi \n\t" \
|
||||
"jmp do_IRQ \n\t");
|
||||
|
||||
// 构造中断入口
|
||||
@ -89,32 +88,11 @@ Build_IRQ(0x36);
|
||||
Build_IRQ(0x37);
|
||||
|
||||
// 初始化中断数组
|
||||
void (*interrupt_table[24])(void) =
|
||||
{
|
||||
IRQ0x20interrupt,
|
||||
IRQ0x21interrupt,
|
||||
IRQ0x22interrupt,
|
||||
IRQ0x23interrupt,
|
||||
IRQ0x24interrupt,
|
||||
IRQ0x25interrupt,
|
||||
IRQ0x26interrupt,
|
||||
IRQ0x27interrupt,
|
||||
IRQ0x28interrupt,
|
||||
IRQ0x29interrupt,
|
||||
IRQ0x2ainterrupt,
|
||||
IRQ0x2binterrupt,
|
||||
IRQ0x2cinterrupt,
|
||||
IRQ0x2dinterrupt,
|
||||
IRQ0x2einterrupt,
|
||||
IRQ0x2finterrupt,
|
||||
IRQ0x30interrupt,
|
||||
IRQ0x31interrupt,
|
||||
IRQ0x32interrupt,
|
||||
IRQ0x33interrupt,
|
||||
IRQ0x34interrupt,
|
||||
IRQ0x35interrupt,
|
||||
IRQ0x36interrupt,
|
||||
IRQ0x37interrupt,
|
||||
void (*interrupt_table[24])(void) = {
|
||||
IRQ0x20interrupt, IRQ0x21interrupt, IRQ0x22interrupt, IRQ0x23interrupt, IRQ0x24interrupt, IRQ0x25interrupt,
|
||||
IRQ0x26interrupt, IRQ0x27interrupt, IRQ0x28interrupt, IRQ0x29interrupt, IRQ0x2ainterrupt, IRQ0x2binterrupt,
|
||||
IRQ0x2cinterrupt, IRQ0x2dinterrupt, IRQ0x2einterrupt, IRQ0x2finterrupt, IRQ0x30interrupt, IRQ0x31interrupt,
|
||||
IRQ0x32interrupt, IRQ0x33interrupt, IRQ0x34interrupt, IRQ0x35interrupt, IRQ0x36interrupt, IRQ0x37interrupt,
|
||||
};
|
||||
|
||||
/**
|
||||
@ -139,18 +117,9 @@ Build_IRQ(0x80); // 系统调用入口
|
||||
void (*syscall_intr_table[1])(void) = {IRQ0x80interrupt};
|
||||
|
||||
// 初始化IPI中断服务程序数组
|
||||
void (*SMP_interrupt_table[SMP_IRQ_NUM])(void) =
|
||||
{
|
||||
IRQ0xc8interrupt,
|
||||
IRQ0xc9interrupt,
|
||||
IRQ0xcainterrupt,
|
||||
IRQ0xcbinterrupt,
|
||||
IRQ0xccinterrupt,
|
||||
IRQ0xcdinterrupt,
|
||||
IRQ0xceinterrupt,
|
||||
IRQ0xcfinterrupt,
|
||||
IRQ0xd0interrupt,
|
||||
IRQ0xd1interrupt,
|
||||
void (*SMP_interrupt_table[SMP_IRQ_NUM])(void) = {
|
||||
IRQ0xc8interrupt, IRQ0xc9interrupt, IRQ0xcainterrupt, IRQ0xcbinterrupt, IRQ0xccinterrupt,
|
||||
IRQ0xcdinterrupt, IRQ0xceinterrupt, IRQ0xcfinterrupt, IRQ0xd0interrupt, IRQ0xd1interrupt,
|
||||
};
|
||||
|
||||
// 初始化local apic中断服务程序数组
|
||||
@ -164,18 +133,9 @@ Build_IRQ(0x9c);
|
||||
Build_IRQ(0x9d);
|
||||
Build_IRQ(0x9e);
|
||||
Build_IRQ(0x9f);
|
||||
void (*local_apic_interrupt_table[LOCAL_APIC_IRQ_NUM])(void) =
|
||||
{
|
||||
IRQ0x96interrupt,
|
||||
IRQ0x97interrupt,
|
||||
IRQ0x98interrupt,
|
||||
IRQ0x99interrupt,
|
||||
IRQ0x9ainterrupt,
|
||||
IRQ0x9binterrupt,
|
||||
IRQ0x9cinterrupt,
|
||||
IRQ0x9dinterrupt,
|
||||
IRQ0x9einterrupt,
|
||||
IRQ0x9finterrupt,
|
||||
void (*local_apic_interrupt_table[LOCAL_APIC_IRQ_NUM])(void) = {
|
||||
IRQ0x96interrupt, IRQ0x97interrupt, IRQ0x98interrupt, IRQ0x99interrupt, IRQ0x9ainterrupt,
|
||||
IRQ0x9binterrupt, IRQ0x9cinterrupt, IRQ0x9dinterrupt, IRQ0x9einterrupt, IRQ0x9finterrupt,
|
||||
};
|
||||
|
||||
/**
|
||||
@ -189,7 +149,8 @@ void (*local_apic_interrupt_table[LOCAL_APIC_IRQ_NUM])(void) =
|
||||
* @param irq_name 中断名
|
||||
* @return int
|
||||
*/
|
||||
int irq_register(ul irq_num, void *arg, void (*handler)(ul irq_num, ul parameter, struct pt_regs *regs), ul paramater, hardware_intr_controller *controller, char *irq_name)
|
||||
int irq_register(ul irq_num, void *arg, void (*handler)(ul irq_num, ul parameter, struct pt_regs *regs), ul paramater,
|
||||
hardware_intr_controller *controller, char *irq_name)
|
||||
{
|
||||
// 由于为I/O APIC分配的中断向量号是从32开始的,因此要减去32才是对应的interrupt_desc的元素
|
||||
irq_desc_t *p = NULL;
|
||||
@ -261,4 +222,4 @@ void irq_init()
|
||||
|
||||
#endif
|
||||
}
|
||||
#pragma GCC optimize("O0")
|
||||
#pragma GCC optimize("O0")
|
||||
|
@ -1,15 +1,19 @@
|
||||
#include "trap.h"
|
||||
#include "gate.h"
|
||||
#include <process/ptrace.h>
|
||||
#include <common/kprint.h>
|
||||
#include <process/process.h>
|
||||
#include <debug/traceback/traceback.h>
|
||||
#include <process/process.h>
|
||||
#include <process/ptrace.h>
|
||||
#include <sched/sched.h>
|
||||
|
||||
extern void ignore_int();
|
||||
|
||||
// 0 #DE 除法错误
|
||||
void do_divide_error(struct pt_regs *regs, unsigned long error_code)
|
||||
{
|
||||
// kerror("do_divide_error(0)");
|
||||
kerror("do_divide_error(0),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\t pid=%d\n", error_code, regs->rsp, regs->rip, proc_current_cpu_id, current_pcb->pid);
|
||||
kerror("do_divide_error(0),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\t pid=%d\n", error_code,
|
||||
regs->rsp, regs->rip, proc_current_cpu_id, current_pcb->pid);
|
||||
traceback(regs);
|
||||
current_pcb->state = PROC_STOPPED;
|
||||
sched();
|
||||
@ -20,7 +24,8 @@ void do_debug(struct pt_regs *regs, unsigned long error_code)
|
||||
{
|
||||
printk("[ ");
|
||||
printk_color(RED, BLACK, "ERROR / TRAP");
|
||||
printk(" ] do_debug(1),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip, proc_current_cpu_id);
|
||||
printk(" ] do_debug(1),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip,
|
||||
proc_current_cpu_id);
|
||||
|
||||
while (1)
|
||||
hlt();
|
||||
@ -32,7 +37,8 @@ void do_nmi(struct pt_regs *regs, unsigned long error_code)
|
||||
|
||||
printk("[ ");
|
||||
printk_color(BLUE, BLACK, "INT");
|
||||
printk(" ] do_nmi(2),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip, proc_current_cpu_id);
|
||||
printk(" ] do_nmi(2),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip,
|
||||
proc_current_cpu_id);
|
||||
|
||||
while (1)
|
||||
hlt();
|
||||
@ -44,7 +50,8 @@ void do_int3(struct pt_regs *regs, unsigned long error_code)
|
||||
|
||||
printk("[ ");
|
||||
printk_color(YELLOW, BLACK, "TRAP");
|
||||
printk(" ] do_int3(3),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip, proc_current_cpu_id);
|
||||
printk(" ] do_int3(3),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip,
|
||||
proc_current_cpu_id);
|
||||
|
||||
while (1)
|
||||
hlt();
|
||||
@ -56,7 +63,8 @@ void do_overflow(struct pt_regs *regs, unsigned long error_code)
|
||||
|
||||
printk("[ ");
|
||||
printk_color(YELLOW, BLACK, "TRAP");
|
||||
printk(" ] do_overflow(4),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip, proc_current_cpu_id);
|
||||
printk(" ] do_overflow(4),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp,
|
||||
regs->rip, proc_current_cpu_id);
|
||||
|
||||
current_pcb->state = PROC_STOPPED;
|
||||
sched();
|
||||
@ -66,7 +74,8 @@ void do_overflow(struct pt_regs *regs, unsigned long error_code)
|
||||
void do_bounds(struct pt_regs *regs, unsigned long error_code)
|
||||
{
|
||||
|
||||
kerror("do_bounds(5),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip, proc_current_cpu_id);
|
||||
kerror("do_bounds(5),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip,
|
||||
proc_current_cpu_id);
|
||||
|
||||
while (1)
|
||||
hlt();
|
||||
@ -76,7 +85,8 @@ void do_bounds(struct pt_regs *regs, unsigned long error_code)
|
||||
void do_undefined_opcode(struct pt_regs *regs, unsigned long error_code)
|
||||
{
|
||||
|
||||
kerror("do_undefined_opcode(6),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d, pid:%ld", error_code, regs->rsp, regs->rip, proc_current_cpu_id, current_pcb->pid);
|
||||
kerror("do_undefined_opcode(6),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d, pid:%ld", error_code,
|
||||
regs->rsp, regs->rip, proc_current_cpu_id, current_pcb->pid);
|
||||
traceback(regs);
|
||||
current_pcb->state = PROC_STOPPED;
|
||||
sched();
|
||||
@ -86,7 +96,8 @@ void do_undefined_opcode(struct pt_regs *regs, unsigned long error_code)
|
||||
void do_dev_not_avaliable(struct pt_regs *regs, unsigned long error_code)
|
||||
{
|
||||
|
||||
kerror("do_dev_not_avaliable(7),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip, proc_current_cpu_id);
|
||||
kerror("do_dev_not_avaliable(7),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp,
|
||||
regs->rip, proc_current_cpu_id);
|
||||
|
||||
current_pcb->state = PROC_STOPPED;
|
||||
sched();
|
||||
@ -98,7 +109,8 @@ void do_double_fault(struct pt_regs *regs, unsigned long error_code)
|
||||
|
||||
printk("[ ");
|
||||
printk_color(RED, BLACK, "Terminate");
|
||||
printk(" ] do_double_fault(8),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip, proc_current_cpu_id);
|
||||
printk(" ] do_double_fault(8),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp,
|
||||
regs->rip, proc_current_cpu_id);
|
||||
traceback(regs);
|
||||
current_pcb->state = PROC_STOPPED;
|
||||
sched();
|
||||
@ -108,7 +120,8 @@ void do_double_fault(struct pt_regs *regs, unsigned long error_code)
|
||||
void do_coprocessor_segment_overrun(struct pt_regs *regs, unsigned long error_code)
|
||||
{
|
||||
|
||||
kerror("do_coprocessor_segment_overrun(9),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip, proc_current_cpu_id);
|
||||
kerror("do_coprocessor_segment_overrun(9),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code,
|
||||
regs->rsp, regs->rip, proc_current_cpu_id);
|
||||
|
||||
current_pcb->state = PROC_STOPPED;
|
||||
sched();
|
||||
@ -120,7 +133,8 @@ void do_invalid_TSS(struct pt_regs *regs, unsigned long error_code)
|
||||
|
||||
printk("[");
|
||||
printk_color(RED, BLACK, "ERROR");
|
||||
printk("] do_invalid_TSS(10),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip, proc_current_cpu_id);
|
||||
printk("] do_invalid_TSS(10),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp,
|
||||
regs->rip, proc_current_cpu_id);
|
||||
|
||||
printk_color(YELLOW, BLACK, "Information:\n");
|
||||
// 解析错误码
|
||||
@ -149,7 +163,8 @@ void do_invalid_TSS(struct pt_regs *regs, unsigned long error_code)
|
||||
void do_segment_not_exists(struct pt_regs *regs, unsigned long error_code)
|
||||
{
|
||||
|
||||
kerror("do_segment_not_exists(11),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip, proc_current_cpu_id);
|
||||
kerror("do_segment_not_exists(11),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp,
|
||||
regs->rip, proc_current_cpu_id);
|
||||
|
||||
current_pcb->state = PROC_STOPPED;
|
||||
sched();
|
||||
@ -159,7 +174,8 @@ void do_segment_not_exists(struct pt_regs *regs, unsigned long error_code)
|
||||
void do_stack_segment_fault(struct pt_regs *regs, unsigned long error_code)
|
||||
{
|
||||
|
||||
kerror("do_stack_segment_fault(12),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip, proc_current_cpu_id);
|
||||
kerror("do_stack_segment_fault(12),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp,
|
||||
regs->rip, proc_current_cpu_id);
|
||||
traceback(regs);
|
||||
current_pcb->state = PROC_STOPPED;
|
||||
sched();
|
||||
@ -169,9 +185,12 @@ void do_stack_segment_fault(struct pt_regs *regs, unsigned long error_code)
|
||||
void do_general_protection(struct pt_regs *regs, unsigned long error_code)
|
||||
{
|
||||
|
||||
kerror("do_general_protection(13),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\tpid=%ld\n", error_code, regs->rsp, regs->rip, proc_current_cpu_id, current_pcb->pid);
|
||||
kerror("do_general_protection(13),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\tpid=%ld\n", error_code,
|
||||
regs->rsp, regs->rip, proc_current_cpu_id, current_pcb->pid);
|
||||
if (error_code & 0x01)
|
||||
printk_color(RED, BLACK, "The exception occurred during delivery of an event external to the program,such as an interrupt or an earlier exception.\n");
|
||||
printk_color(RED, BLACK,
|
||||
"The exception occurred during delivery of an event external to the program,such as an interrupt "
|
||||
"or an earlier exception.\n");
|
||||
|
||||
if (error_code & 0x02)
|
||||
printk_color(RED, BLACK, "Refers to a gate descriptor in the IDT;\n");
|
||||
@ -196,10 +215,10 @@ void do_page_fault(struct pt_regs *regs, unsigned long error_code)
|
||||
|
||||
unsigned long cr2 = 0;
|
||||
|
||||
__asm__ __volatile__("movq %%cr2, %0"
|
||||
: "=r"(cr2)::"memory");
|
||||
__asm__ __volatile__("movq %%cr2, %0" : "=r"(cr2)::"memory");
|
||||
|
||||
kerror("do_page_fault(14),Error code :%#018lx,RSP:%#018lx, RBP=%#018lx, RIP:%#018lx CPU:%d, pid=%d\n", error_code, regs->rsp, regs->rbp, regs->rip, proc_current_cpu_id, current_pcb->pid);
|
||||
kerror("do_page_fault(14),Error code :%#018lx,RSP:%#018lx, RBP=%#018lx, RIP:%#018lx CPU:%d, pid=%d\n", error_code,
|
||||
regs->rsp, regs->rbp, regs->rip, proc_current_cpu_id, current_pcb->pid);
|
||||
kerror("regs->rax = %#018lx\n", regs->rax);
|
||||
if (!(error_code & 0x01))
|
||||
printk_color(RED, BLACK, "Page Not-Present,\t");
|
||||
@ -223,7 +242,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long error_code)
|
||||
printk_color(RED, BLACK, "\n");
|
||||
|
||||
printk_color(RED, BLACK, "CR2:%#018lx\n", cr2);
|
||||
|
||||
|
||||
traceback(regs);
|
||||
current_pcb->state = PROC_STOPPED;
|
||||
sched();
|
||||
@ -235,7 +254,8 @@ void do_page_fault(struct pt_regs *regs, unsigned long error_code)
|
||||
void do_x87_FPU_error(struct pt_regs *regs, unsigned long error_code)
|
||||
{
|
||||
|
||||
kerror("do_x87_FPU_error(16),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip, proc_current_cpu_id);
|
||||
kerror("do_x87_FPU_error(16),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp,
|
||||
regs->rip, proc_current_cpu_id);
|
||||
|
||||
while (1)
|
||||
hlt();
|
||||
@ -245,7 +265,8 @@ void do_x87_FPU_error(struct pt_regs *regs, unsigned long error_code)
|
||||
void do_alignment_check(struct pt_regs *regs, unsigned long error_code)
|
||||
{
|
||||
|
||||
kerror("do_alignment_check(17),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip, proc_current_cpu_id);
|
||||
kerror("do_alignment_check(17),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp,
|
||||
regs->rip, proc_current_cpu_id);
|
||||
|
||||
current_pcb->state = PROC_STOPPED;
|
||||
sched();
|
||||
@ -255,7 +276,8 @@ void do_alignment_check(struct pt_regs *regs, unsigned long error_code)
|
||||
void do_machine_check(struct pt_regs *regs, unsigned long error_code)
|
||||
{
|
||||
|
||||
kerror("do_machine_check(18),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip, proc_current_cpu_id);
|
||||
kerror("do_machine_check(18),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp,
|
||||
regs->rip, proc_current_cpu_id);
|
||||
|
||||
current_pcb->state = PROC_STOPPED;
|
||||
sched();
|
||||
@ -265,7 +287,8 @@ void do_machine_check(struct pt_regs *regs, unsigned long error_code)
|
||||
void do_SIMD_exception(struct pt_regs *regs, unsigned long error_code)
|
||||
{
|
||||
|
||||
kerror("do_SIMD_exception(19),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip, proc_current_cpu_id);
|
||||
kerror("do_SIMD_exception(19),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp,
|
||||
regs->rip, proc_current_cpu_id);
|
||||
|
||||
current_pcb->state = PROC_STOPPED;
|
||||
sched();
|
||||
@ -275,7 +298,8 @@ void do_SIMD_exception(struct pt_regs *regs, unsigned long error_code)
|
||||
void do_virtualization_exception(struct pt_regs *regs, unsigned long error_code)
|
||||
{
|
||||
|
||||
kerror("do_virtualization_exception(20),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip, proc_current_cpu_id);
|
||||
kerror("do_virtualization_exception(20),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code,
|
||||
regs->rsp, regs->rip, proc_current_cpu_id);
|
||||
|
||||
current_pcb->state = PROC_STOPPED;
|
||||
sched();
|
||||
@ -283,8 +307,24 @@ void do_virtualization_exception(struct pt_regs *regs, unsigned long error_code)
|
||||
|
||||
// 21-21 Intel保留,请勿使用
|
||||
|
||||
/**
|
||||
* @brief 当系统收到未知的中断时,执行此处理函数
|
||||
*
|
||||
* @param regs
|
||||
* @param error_code
|
||||
*/
|
||||
void ignore_int_handler(struct pt_regs *regs, unsigned long error_code)
|
||||
{
|
||||
kwarn("Unknown interrupt or fault at RIP.\n");
|
||||
}
|
||||
|
||||
void sys_vector_init()
|
||||
{
|
||||
// 将idt重置为新的ignore_int入点(此前在head.S中有设置,
|
||||
// 但是那个不完整,某些版本的编译器的输出,在真机运行时会破坏进程执行环境,从而导致#GP
|
||||
for (int i = 0; i < 256; ++i)
|
||||
set_intr_gate(i, 0, ignore_int);
|
||||
|
||||
set_trap_gate(0, 0, divide_error);
|
||||
set_trap_gate(1, 0, debug);
|
||||
set_intr_gate(2, 0, nmi);
|
||||
|
@ -10,7 +10,7 @@ ECHO:
|
||||
|
||||
|
||||
$(kernel_fs_objs): ECHO
|
||||
gcc $(CFLAGS) -c $@ -o $@.o
|
||||
$(CC) $(CFLAGS) -c $@ -o $@.o
|
||||
|
||||
$(kernel_fs_subdirs): ECHO
|
||||
$(MAKE) -C $@ all CFLAGS="$(CFLAGS)" ASFLAGS="$(ASFLAGS)" PIC="$(PIC)"
|
||||
|
@ -10,7 +10,7 @@ ECHO:
|
||||
|
||||
|
||||
$(kernel_fs_vfs_objs): ECHO
|
||||
gcc $(CFLAGS) -c $@ -o $@.o
|
||||
$(CC) $(CFLAGS) -c $@ -o $@.o
|
||||
|
||||
|
||||
all: $(kernel_fs_vfs_objs)
|
||||
|
@ -398,7 +398,6 @@ uint64_t do_open(const char *filename, int flags)
|
||||
|
||||
// 寻找文件
|
||||
struct vfs_dir_entry_t *dentry = vfs_path_walk(path, 0);
|
||||
|
||||
if (dentry == NULL && flags & O_CREAT)
|
||||
{
|
||||
// 先找到倒数第二级目录
|
||||
|
@ -10,7 +10,7 @@ ECHO:
|
||||
|
||||
|
||||
$(kernel_fs_devfs_objs): ECHO
|
||||
gcc $(CFLAGS) -c $@ -o $@.o
|
||||
$(CC) $(CFLAGS) -c $@ -o $@.o
|
||||
|
||||
|
||||
all: $(kernel_fs_devfs_objs)
|
||||
|
@ -10,7 +10,7 @@ ECHO:
|
||||
|
||||
|
||||
$(kernel_fs_fat32_objs): ECHO
|
||||
gcc $(CFLAGS) -c $@ -o $@.o
|
||||
$(CC) $(CFLAGS) -c $@ -o $@.o
|
||||
|
||||
|
||||
all: $(kernel_fs_fat32_objs)
|
||||
|
@ -10,7 +10,7 @@ ECHO:
|
||||
|
||||
|
||||
$(kernel_fs_rootfs_objs): ECHO
|
||||
gcc $(CFLAGS) -c $@ -o $@.o
|
||||
$(CC) $(CFLAGS) -c $@ -o $@.o
|
||||
|
||||
|
||||
all: $(kernel_fs_rootfs_objs)
|
||||
|
@ -326,6 +326,7 @@ entry64:
|
||||
jnc start_smp
|
||||
|
||||
setup_IDT:
|
||||
// 该部分代码只在启动初期使用,后面的c文件中会重新设置IDT,
|
||||
leaq m_ignore_int(%rip), %rdx // 将ignore_int的地址暂时存到中段描述符的高8B
|
||||
movq $(0x08 << 16), %rax // 设置段选择子。由IDT结构和段选择子结构可知,本行设置段基地址为0x100000,TI=0,RPL=0
|
||||
movw %dx, %ax
|
||||
@ -460,6 +461,7 @@ go_to_smp_kernel:
|
||||
.quad smp_ap_start
|
||||
|
||||
// ==== 异常/中断处理模块 ignore int: 忽略中断
|
||||
// (该部分代码只在启动初期使用,后面的c文件中会重新设置IDT,从而重设ignore_int的中断入点)
|
||||
m_ignore_int:
|
||||
// 切换到c语言的ignore_int
|
||||
movq go_to_ignore_int(%rip), %rax
|
||||
@ -470,7 +472,7 @@ m_ignore_int:
|
||||
|
||||
|
||||
go_to_ignore_int:
|
||||
.quad ignore_int
|
||||
.quad ignore_int_handler
|
||||
|
||||
|
||||
ENTRY(head_stack_start)
|
||||
|
@ -4,7 +4,7 @@ all: pipe.o
|
||||
CFLAGS += -I .
|
||||
|
||||
pipe.o: pipe.c
|
||||
gcc $(CFLAGS) -c pipe.c -o pipe.o
|
||||
$(CC) $(CFLAGS) -c pipe.c -o pipe.o
|
||||
|
||||
clean:
|
||||
echo "Done."
|
@ -5,16 +5,16 @@ CFLAGS += -I .
|
||||
all: ktest.o bitree.o kfifo.o mutex.o idr.o
|
||||
|
||||
ktest.o: ktest.c
|
||||
gcc $(CFLAGS) -c ktest.c -o ktest.o
|
||||
$(CC) $(CFLAGS) -c ktest.c -o ktest.o
|
||||
|
||||
bitree.o: test-bitree.c
|
||||
gcc $(CFLAGS) -c test-bitree.c -o test-bitree.o
|
||||
$(CC) $(CFLAGS) -c test-bitree.c -o test-bitree.o
|
||||
|
||||
kfifo.o: test-kfifo.c
|
||||
gcc $(CFLAGS) -c test-kfifo.c -o test-kfifo.o
|
||||
$(CC) $(CFLAGS) -c test-kfifo.c -o test-kfifo.o
|
||||
|
||||
mutex.o: test-mutex.c
|
||||
gcc $(CFLAGS) -c test-mutex.c -o test-mutex.o
|
||||
$(CC) $(CFLAGS) -c test-mutex.c -o test-mutex.o
|
||||
|
||||
idr.o: test-idr.c
|
||||
gcc $(CFLAGS) -c test-idr.c -o test-idr.o
|
||||
$(CC) $(CFLAGS) -c test-idr.c -o test-idr.o
|
@ -12,7 +12,7 @@ $(kernel_lib_subdirs): ECHO
|
||||
$(MAKE) -C $@ all CFLAGS="$(CFLAGS)" ASFLAGS="$(ASFLAGS)" PIC="$(PIC)"
|
||||
|
||||
$(kernel_lib_objs): ECHO
|
||||
gcc $(CFLAGS) -c $@ -o $@.o
|
||||
$(CC) $(CFLAGS) -c $@ -o $@.o
|
||||
|
||||
all: $(kernel_lib_objs) $(kernel_lib_subdirs)
|
||||
@echo $(kernel_lib_objs)
|
||||
|
@ -32,15 +32,14 @@ void idr_init(struct idr *idp)
|
||||
*/
|
||||
static void __move_to_free_list(struct idr *idp, struct idr_layer *p)
|
||||
{
|
||||
unsigned long flags;
|
||||
spin_lock_irqsave(&idp->lock, flags);
|
||||
spin_lock(&idp->lock);
|
||||
|
||||
// 插入free_list
|
||||
p->ary[0] = idp->free_list;
|
||||
idp->free_list = p;
|
||||
++(idp->id_free_cnt);
|
||||
|
||||
spin_unlock_irqrestore(&idp->lock, flags);
|
||||
spin_unlock(&idp->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -60,8 +59,7 @@ static void *__get_from_free_list(struct idr *idp)
|
||||
}
|
||||
}
|
||||
|
||||
unsigned long flags;
|
||||
spin_lock_irqsave(&idp->lock, flags);
|
||||
spin_lock(&idp->lock);
|
||||
|
||||
// free_list还有节点
|
||||
struct idr_layer *item = idp->free_list;
|
||||
@ -69,7 +67,7 @@ static void *__get_from_free_list(struct idr *idp)
|
||||
item->ary[0] = NULL; // 记得清空原来的数据
|
||||
--(idp->id_free_cnt);
|
||||
|
||||
spin_unlock_irqrestore(&idp->lock, flags);
|
||||
spin_unlock(&idp->lock);
|
||||
|
||||
return item;
|
||||
}
|
||||
@ -316,9 +314,8 @@ static __always_inline void __idr_erase_full(struct idr *idp, int id, struct idr
|
||||
// 特判根节点是否只剩0号儿子节点 (注意还要layer > 0)
|
||||
// (注意,有可能出现idp->top=NULL)
|
||||
// bitmap: 1000...000/00.....000
|
||||
while (idp->top != NULL &&
|
||||
((idp->top->bitmap <= 1 && idp->top->layer > 0) || // 一条链的情况
|
||||
(idp->top->layer == 0 && idp->top->bitmap == 0))) // 最后一个点的情况
|
||||
while (idp->top != NULL && ((idp->top->bitmap <= 1 && idp->top->layer > 0) || // 一条链的情况
|
||||
(idp->top->layer == 0 && idp->top->bitmap == 0))) // 最后一个点的情况
|
||||
{
|
||||
struct idr_layer *t = idp->top->layer ? idp->top->ary[0] : NULL;
|
||||
__idr_layer_free(idp->top);
|
||||
@ -505,7 +502,8 @@ void *idr_find(struct idr *idp, int id)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 返回id大于 start_id 的数据指针(即非空闲id对应的指针), 如果没有则返回NULL; 可以传入nextid指针,获取下一个id; 时间复杂度O(log_64(n)), 空间复杂度O(log_64(n)) 约为 6;
|
||||
* @brief 返回id大于 start_id 的数据指针(即非空闲id对应的指针), 如果没有则返回NULL; 可以传入nextid指针,获取下一个id;
|
||||
* 时间复杂度O(log_64(n)), 空间复杂度O(log_64(n)) 约为 6;
|
||||
*
|
||||
* @param idp
|
||||
* @param start_id
|
||||
@ -699,8 +697,7 @@ int ida_pre_get(struct ida *ida_p, gfp_t gfp_mask)
|
||||
if (idr_pre_get(&ida_p->idr, gfp_mask) != 0)
|
||||
return -ENOMEM;
|
||||
|
||||
unsigned long flags;
|
||||
spin_lock_irqsave(&ida_p->idr.lock, flags);
|
||||
spin_lock(&ida_p->idr.lock);
|
||||
|
||||
if (NULL == ida_p->free_list)
|
||||
{
|
||||
@ -708,13 +705,13 @@ int ida_pre_get(struct ida *ida_p, gfp_t gfp_mask)
|
||||
bitmap = kzalloc(sizeof(struct ida_bitmap), gfp_mask);
|
||||
if (NULL == bitmap)
|
||||
{
|
||||
spin_unlock_irqrestore(&ida_p->idr.lock, flags);
|
||||
spin_unlock(&ida_p->idr.lock);
|
||||
return -ENOMEM;
|
||||
}
|
||||
ida_p->free_list = bitmap;
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&ida_p->idr.lock, flags);
|
||||
spin_unlock(&ida_p->idr.lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -5,4 +5,4 @@ CFLAGS += -I .
|
||||
|
||||
|
||||
elf.o: elf.c
|
||||
gcc $(CFLAGS) -c elf.c -o elf.o
|
||||
$(CC) $(CFLAGS) -c elf.c -o elf.o
|
||||
|
@ -4,10 +4,10 @@ all: screen_manager.o textui.o textui-render.o
|
||||
CFLAGS += -I .
|
||||
|
||||
screen_manager.o: screen_manager.c
|
||||
gcc $(CFLAGS) -c screen_manager.c -o screen_manager.o
|
||||
$(CC) $(CFLAGS) -c screen_manager.c -o screen_manager.o
|
||||
|
||||
textui.o: textui.c
|
||||
gcc $(CFLAGS) -c textui.c -o textui.o
|
||||
$(CC) $(CFLAGS) -c textui.c -o textui.o
|
||||
|
||||
textui-render.o: textui-render.c
|
||||
gcc $(CFLAGS) -c textui-render.c -o textui-render.o
|
||||
$(CC) $(CFLAGS) -c textui-render.c -o textui-render.o
|
||||
|
@ -181,7 +181,8 @@ static int __textui_putchar_window(struct textui_window_t *window, uint16_t char
|
||||
++vline->index;
|
||||
textui_refresh_characters(window, window->vline_operating, vline->index - 1, 1);
|
||||
// 换行
|
||||
if (vline->index >= window->chars_per_line)
|
||||
// 加入光标后,因为会识别光标,所以需超过该行最大字符数才能创建新行
|
||||
if (vline->index > window->chars_per_line)
|
||||
{
|
||||
__textui_new_line(window, window->vline_operating);
|
||||
}
|
||||
@ -295,7 +296,7 @@ int textui_putchar(uint16_t character, uint32_t FRcolor, uint32_t BKcolor)
|
||||
/**
|
||||
* @brief 初始化text ui框架
|
||||
*
|
||||
* @return int
|
||||
* @return int
|
||||
*/
|
||||
int textui_init()
|
||||
{
|
||||
|
@ -7,7 +7,7 @@ ECHO:
|
||||
@echo "$@"
|
||||
|
||||
$(kernel_lib_sys_objs): ECHO
|
||||
gcc $(CFLAGS) -c $@ -o $@.o
|
||||
$(CC) $(CFLAGS) -c $@ -o $@.o
|
||||
|
||||
all: $(kernel_lib_sys_objs)
|
||||
@echo $(kernel_lib_sys_objs)
|
||||
|
@ -209,10 +209,4 @@ void Start_Kernel(void)
|
||||
while (1)
|
||||
pause();
|
||||
}
|
||||
|
||||
void ignore_int()
|
||||
{
|
||||
kwarn("Unknown interrupt or fault at RIP.\n");
|
||||
sti();
|
||||
}
|
||||
#pragma GCC pop_options
|
@ -5,25 +5,25 @@ CFLAGS += -I .
|
||||
all:mm.o slab.o mm-stat.o vma.o mmap.o utils.o mmio.o mmio-buddy.o
|
||||
|
||||
mm.o: mm.c
|
||||
gcc $(CFLAGS) -c mm.c -o mm.o
|
||||
$(CC) $(CFLAGS) -c mm.c -o mm.o
|
||||
|
||||
slab.o: slab.c
|
||||
gcc $(CFLAGS) -c slab.c -o slab.o
|
||||
$(CC) $(CFLAGS) -c slab.c -o slab.o
|
||||
|
||||
mm-stat.o: mm-stat.c
|
||||
gcc $(CFLAGS) -c mm-stat.c -o mm-stat.o
|
||||
$(CC) $(CFLAGS) -c mm-stat.c -o mm-stat.o
|
||||
|
||||
vma.o: vma.c
|
||||
gcc $(CFLAGS) -c vma.c -o vma.o
|
||||
$(CC) $(CFLAGS) -c vma.c -o vma.o
|
||||
|
||||
mmap.o: mmap.c
|
||||
gcc $(CFLAGS) -c mmap.c -o mmap.o
|
||||
$(CC) $(CFLAGS) -c mmap.c -o mmap.o
|
||||
|
||||
utils.o: utils.c
|
||||
gcc $(CFLAGS) -c utils.c -o utils.o
|
||||
$(CC) $(CFLAGS) -c utils.c -o utils.o
|
||||
|
||||
mmio.o: mmio.c
|
||||
gcc $(CFLAGS) -c mmio.c -o mmio.o
|
||||
$(CC) $(CFLAGS) -c mmio.c -o mmio.o
|
||||
|
||||
mmio-buddy.o: mmio-buddy.c
|
||||
gcc $(CFLAGS) -c mmio-buddy.c -o mmio-buddy.o
|
||||
$(CC) $(CFLAGS) -c mmio-buddy.c -o mmio-buddy.o
|
@ -9,10 +9,10 @@ ECHO:
|
||||
|
||||
|
||||
$(kernel_process_objs): ECHO
|
||||
gcc $(CFLAGS) -c $@ -o $@.o
|
||||
$(CC) $(CFLAGS) -c $@ -o $@.o
|
||||
|
||||
procs.o: proc.S
|
||||
gcc -E proc.S > _proc.s
|
||||
$(CC) -E proc.S > _proc.s
|
||||
as $(ASFLAGS) -o procs.o _proc.s
|
||||
|
||||
all: procs.o $(kernel_process_objs)
|
||||
|
@ -27,7 +27,7 @@ struct kthread_create_info_t
|
||||
void *data;
|
||||
int node;
|
||||
|
||||
// kthreadd守护进程传递给kthread_create的结果
|
||||
// kthreadd守护进程传递给kthread_create的结果, 成功则返回PCB,不成功则该值为负数错误码。若该值为NULL,意味着创建过程尚未完成
|
||||
struct process_control_block *result;
|
||||
|
||||
struct List list;
|
||||
@ -170,6 +170,7 @@ static int kthread(void *_create)
|
||||
// 将当前pcb返回给创建者
|
||||
create->result = current_pcb;
|
||||
|
||||
current_pcb->state &= ~PROC_RUNNING; // 设置当前进程不是RUNNING态
|
||||
// 发起调度,使得当前内核线程休眠。直到创建者通过process_wakeup将当前内核线程唤醒
|
||||
sched();
|
||||
|
||||
|
@ -44,7 +44,8 @@
|
||||
.next_pcb = &proc, \
|
||||
.parent_pcb = &proc, \
|
||||
.exit_code = 0, \
|
||||
.wait_child_proc_exit = 0 \
|
||||
.wait_child_proc_exit = 0, \
|
||||
.worker_private = NULL \
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2,7 +2,12 @@
|
||||
CFLAGS += -I .
|
||||
|
||||
|
||||
all: sched.o
|
||||
all: sched.o cfs.o
|
||||
|
||||
cfs.o: cfs.c
|
||||
$(CC) $(CFLAGS) -c cfs.c -o cfs.o
|
||||
|
||||
sched.o: sched.c
|
||||
gcc $(CFLAGS) -c sched.c -o sched.o
|
||||
$(CC) $(CFLAGS) -c sched.c -o sched.o
|
||||
clean:
|
||||
echo "Done."
|
154
kernel/sched/cfs.c
Normal file
154
kernel/sched/cfs.c
Normal file
@ -0,0 +1,154 @@
|
||||
#include "cfs.h"
|
||||
#include <common/kprint.h>
|
||||
#include <driver/video/video.h>
|
||||
#include <common/spinlock.h>
|
||||
|
||||
struct sched_queue_t sched_cfs_ready_queue[MAX_CPU_NUM]; // 就绪队列
|
||||
|
||||
/**
|
||||
* @brief 从就绪队列中取出PCB
|
||||
*
|
||||
* @return struct process_control_block*
|
||||
*/
|
||||
struct process_control_block *sched_cfs_dequeue()
|
||||
{
|
||||
if (list_empty(&sched_cfs_ready_queue[proc_current_cpu_id].proc_queue.list))
|
||||
{
|
||||
// kdebug("list empty, count=%d", sched_cfs_ready_queue[proc_current_cpu_id].count);
|
||||
return &initial_proc_union.pcb;
|
||||
}
|
||||
|
||||
struct process_control_block *proc = container_of(list_next(&sched_cfs_ready_queue[proc_current_cpu_id].proc_queue.list), struct process_control_block, list);
|
||||
|
||||
list_del(&proc->list);
|
||||
--sched_cfs_ready_queue[proc_current_cpu_id].count;
|
||||
return proc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 将PCB加入就绪队列
|
||||
*
|
||||
* @param pcb
|
||||
*/
|
||||
void sched_cfs_enqueue(struct process_control_block *pcb)
|
||||
{
|
||||
if (pcb == initial_proc[proc_current_cpu_id])
|
||||
return;
|
||||
struct process_control_block *proc = container_of(list_next(&sched_cfs_ready_queue[proc_current_cpu_id].proc_queue.list), struct process_control_block, list);
|
||||
if ((list_empty(&sched_cfs_ready_queue[proc_current_cpu_id].proc_queue.list)) == 0)
|
||||
{
|
||||
while (proc->virtual_runtime < pcb->virtual_runtime)
|
||||
{
|
||||
proc = container_of(list_next(&proc->list), struct process_control_block, list);
|
||||
}
|
||||
}
|
||||
list_append(&proc->list, &pcb->list);
|
||||
++sched_cfs_ready_queue[proc_current_cpu_id].count;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 调度函数
|
||||
*
|
||||
*/
|
||||
void sched_cfs()
|
||||
{
|
||||
|
||||
cli();
|
||||
|
||||
current_pcb->flags &= ~PF_NEED_SCHED;
|
||||
// kdebug("current_pcb pid= %d", current_pcb->pid);
|
||||
struct process_control_block *proc = sched_cfs_dequeue();
|
||||
// kdebug("sched_cfs_ready_queue[proc_current_cpu_id].count = %d", sched_cfs_ready_queue[proc_current_cpu_id].count);
|
||||
if (current_pcb->virtual_runtime >= proc->virtual_runtime || !(current_pcb->state & PROC_RUNNING)) // 当前进程运行时间大于了下一进程的运行时间,进行切换
|
||||
{
|
||||
|
||||
// kdebug("current_pcb->virtual_runtime = %d,proc->vt= %d", current_pcb->virtual_runtime, proc->virtual_runtime);
|
||||
if (current_pcb->state & PROC_RUNNING) // 本次切换由于时间片到期引发,则再次加入就绪队列,否则交由其它功能模块进行管理
|
||||
sched_cfs_enqueue(current_pcb);
|
||||
// kdebug("proc->pid=%d, count=%d", proc->pid, sched_cfs_ready_queue[proc_current_cpu_id].count);
|
||||
if (sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies <= 0)
|
||||
{
|
||||
switch (proc->priority)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies = 4 / sched_cfs_ready_queue[proc_current_cpu_id].count;
|
||||
break;
|
||||
case 2:
|
||||
default:
|
||||
sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies = (4 / sched_cfs_ready_queue[proc_current_cpu_id].count) << 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
process_switch_mm(proc);
|
||||
|
||||
switch_proc(current_pcb, proc);
|
||||
}
|
||||
else // 不进行切换
|
||||
{
|
||||
// kdebug("not switch.");
|
||||
sched_cfs_enqueue(proc);
|
||||
|
||||
if (sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies <= 0)
|
||||
{
|
||||
switch (proc->priority)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies = 4 / sched_cfs_ready_queue[proc_current_cpu_id].count;
|
||||
break;
|
||||
case 2:
|
||||
default:
|
||||
|
||||
sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies = (4 / sched_cfs_ready_queue[proc_current_cpu_id].count) << 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sti();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 当时钟中断到达时,更新时间片
|
||||
*
|
||||
*/
|
||||
void sched_update_jiffies()
|
||||
{
|
||||
|
||||
switch (current_pcb->priority)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
--sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies;
|
||||
++current_pcb->virtual_runtime;
|
||||
break;
|
||||
case 2:
|
||||
default:
|
||||
sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies -= 2;
|
||||
current_pcb->virtual_runtime += 2;
|
||||
break;
|
||||
}
|
||||
// 时间片耗尽,标记可调度
|
||||
if (sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies <= 0)
|
||||
current_pcb->flags |= PF_NEED_SCHED;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 初始化CFS调度器
|
||||
*
|
||||
*/
|
||||
void sched_cfs_init()
|
||||
{
|
||||
memset(&sched_cfs_ready_queue, 0, sizeof(struct sched_queue_t) * MAX_CPU_NUM);
|
||||
for (int i = 0; i < MAX_CPU_NUM; ++i)
|
||||
{
|
||||
|
||||
list_init(&sched_cfs_ready_queue[i].proc_queue.list);
|
||||
sched_cfs_ready_queue[i].count = 1; // 因为存在IDLE进程,因此为1
|
||||
sched_cfs_ready_queue[i].cpu_exec_proc_jiffies = 5;
|
||||
sched_cfs_ready_queue[i].proc_queue.virtual_runtime = 0x7fffffffffffffff;
|
||||
}
|
||||
}
|
39
kernel/sched/cfs.h
Normal file
39
kernel/sched/cfs.h
Normal file
@ -0,0 +1,39 @@
|
||||
#pragma once
|
||||
|
||||
#include <common/glib.h>
|
||||
#include <process/process.h>
|
||||
|
||||
// @todo: 用红黑树重写cfs的队列
|
||||
struct sched_queue_t
|
||||
{
|
||||
long count; // 当前队列中的数量
|
||||
long cpu_exec_proc_jiffies; // 进程可执行的时间片数量
|
||||
struct process_control_block proc_queue;
|
||||
};
|
||||
|
||||
extern struct sched_queue_t sched_cfs_ready_queue[MAX_CPU_NUM]; // 就绪队列
|
||||
|
||||
/**
|
||||
* @brief 调度函数
|
||||
*
|
||||
*/
|
||||
void sched_cfs();
|
||||
|
||||
/**
|
||||
* @brief 将PCB加入就绪队列
|
||||
*
|
||||
* @param pcb
|
||||
*/
|
||||
void sched_cfs_enqueue(struct process_control_block *pcb);
|
||||
|
||||
/**
|
||||
* @brief 从就绪队列中取出PCB
|
||||
*
|
||||
* @return struct process_control_block*
|
||||
*/
|
||||
struct process_control_block *sched_cfs_dequeue();
|
||||
/**
|
||||
* @brief 初始化CFS进程调度器
|
||||
*
|
||||
*/
|
||||
void sched_cfs_init();
|
@ -2,54 +2,11 @@
|
||||
#include <common/kprint.h>
|
||||
#include <driver/video/video.h>
|
||||
#include <common/spinlock.h>
|
||||
|
||||
|
||||
struct sched_queue_t sched_cfs_ready_queue[MAX_CPU_NUM]; // 就绪队列
|
||||
|
||||
/**
|
||||
* @brief 从就绪队列中取出PCB
|
||||
*
|
||||
* @return struct process_control_block*
|
||||
*/
|
||||
struct process_control_block *sched_cfs_dequeue()
|
||||
{
|
||||
if (list_empty(&sched_cfs_ready_queue[proc_current_cpu_id].proc_queue.list))
|
||||
{
|
||||
// kdebug("list empty, count=%d", sched_cfs_ready_queue[proc_current_cpu_id].count);
|
||||
return &initial_proc_union.pcb;
|
||||
}
|
||||
|
||||
struct process_control_block *proc = container_of(list_next(&sched_cfs_ready_queue[proc_current_cpu_id].proc_queue.list), struct process_control_block, list);
|
||||
|
||||
list_del(&proc->list);
|
||||
--sched_cfs_ready_queue[proc_current_cpu_id].count;
|
||||
return proc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 将PCB加入就绪队列
|
||||
*
|
||||
* @param pcb
|
||||
*/
|
||||
void sched_cfs_enqueue(struct process_control_block *pcb)
|
||||
{
|
||||
if (pcb == initial_proc[proc_current_cpu_id])
|
||||
return;
|
||||
struct process_control_block *proc = container_of(list_next(&sched_cfs_ready_queue[proc_current_cpu_id].proc_queue.list), struct process_control_block, list);
|
||||
if ((list_empty(&sched_cfs_ready_queue[proc_current_cpu_id].proc_queue.list)) == 0)
|
||||
{
|
||||
while (proc->virtual_runtime < pcb->virtual_runtime)
|
||||
{
|
||||
proc = container_of(list_next(&proc->list), struct process_control_block, list);
|
||||
}
|
||||
}
|
||||
list_append(&proc->list, &pcb->list);
|
||||
++sched_cfs_ready_queue[proc_current_cpu_id].count;
|
||||
}
|
||||
#include <sched/cfs.h>
|
||||
|
||||
/**
|
||||
* @brief 包裹shced_cfs_enqueue(),将PCB加入就绪队列
|
||||
*
|
||||
*
|
||||
* @param pcb
|
||||
*/
|
||||
void sched_enqueue(struct process_control_block *pcb)
|
||||
@ -57,124 +14,16 @@ void sched_enqueue(struct process_control_block *pcb)
|
||||
sched_cfs_enqueue(pcb);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 调度函数
|
||||
*
|
||||
*/
|
||||
void sched_cfs()
|
||||
{
|
||||
|
||||
cli();
|
||||
|
||||
current_pcb->flags &= ~PF_NEED_SCHED;
|
||||
struct process_control_block *proc = sched_cfs_dequeue();
|
||||
// kdebug("sched_cfs_ready_queue[proc_current_cpu_id].count = %d", sched_cfs_ready_queue[proc_current_cpu_id].count);
|
||||
if (current_pcb->virtual_runtime >= proc->virtual_runtime || !(current_pcb->state & PROC_RUNNING)) // 当前进程运行时间大于了下一进程的运行时间,进行切换
|
||||
{
|
||||
|
||||
if (current_pcb->state & PROC_RUNNING) // 本次切换由于时间片到期引发,则再次加入就绪队列,否则交由其它功能模块进行管理
|
||||
sched_cfs_enqueue(current_pcb);
|
||||
// kdebug("proc->pid=%d, count=%d", proc->pid, sched_cfs_ready_queue[proc_current_cpu_id].count);
|
||||
if (sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies <= 0)
|
||||
{
|
||||
switch (proc->priority)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies = 4 / sched_cfs_ready_queue[proc_current_cpu_id].count;
|
||||
break;
|
||||
case 2:
|
||||
default:
|
||||
sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies = (4 / sched_cfs_ready_queue[proc_current_cpu_id].count) << 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// if (proc->pid == 0)
|
||||
// {
|
||||
// kdebug("switch to pid0, current pid%ld, vrt=%ld pid0 vrt=%ld", current_pcb->pid, current_pcb->virtual_runtime, proc->virtual_runtime);
|
||||
// if(current_pcb->state != PROC_RUNNING)
|
||||
// kdebug("current_pcb->state!=PROC_RUNNING");
|
||||
// }
|
||||
|
||||
process_switch_mm(proc);
|
||||
|
||||
switch_proc(current_pcb, proc);
|
||||
}
|
||||
else // 不进行切换
|
||||
{
|
||||
// kdebug("not switch.");
|
||||
sched_cfs_enqueue(proc);
|
||||
|
||||
if (sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies <= 0)
|
||||
{
|
||||
switch (proc->priority)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies = 4 / sched_cfs_ready_queue[proc_current_cpu_id].count;
|
||||
// sched_cfs_ready_queue.cpu_exec_proc_jiffies = 5;
|
||||
break;
|
||||
case 2:
|
||||
default:
|
||||
// sched_cfs_ready_queue.cpu_exec_proc_jiffies = 5;
|
||||
|
||||
sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies = (4 / sched_cfs_ready_queue[proc_current_cpu_id].count) << 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sti();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 包裹sched_cfs(),调度函数
|
||||
*
|
||||
*
|
||||
*/
|
||||
void sched()
|
||||
{
|
||||
sched_cfs();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 当时钟中断到达时,更新时间片
|
||||
*
|
||||
*/
|
||||
void sched_update_jiffies()
|
||||
{
|
||||
|
||||
switch (current_pcb->priority)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
--sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies;
|
||||
++current_pcb->virtual_runtime;
|
||||
break;
|
||||
case 2:
|
||||
default:
|
||||
sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies -= 2;
|
||||
current_pcb->virtual_runtime += 2;
|
||||
break;
|
||||
}
|
||||
// 时间片耗尽,标记可调度
|
||||
if (sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies <= 0)
|
||||
current_pcb->flags |= PF_NEED_SCHED;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 初始化进程调度器
|
||||
*
|
||||
*/
|
||||
void sched_init()
|
||||
{
|
||||
memset(&sched_cfs_ready_queue, 0, sizeof(struct sched_queue_t) * MAX_CPU_NUM);
|
||||
for (int i = 0; i < MAX_CPU_NUM; ++i)
|
||||
{
|
||||
|
||||
list_init(&sched_cfs_ready_queue[i].proc_queue.list);
|
||||
sched_cfs_ready_queue[i].count = 1; // 因为存在IDLE进程,因此为1
|
||||
sched_cfs_ready_queue[i].cpu_exec_proc_jiffies = 5;
|
||||
sched_cfs_ready_queue[i].proc_queue.virtual_runtime = 0x7fffffffffffffff;
|
||||
}
|
||||
sched_cfs_init();
|
||||
}
|
@ -2,60 +2,23 @@
|
||||
|
||||
#include <common/glib.h>
|
||||
#include <process/process.h>
|
||||
|
||||
// @todo: 用红黑树重写cfs的队列
|
||||
struct sched_queue_t
|
||||
{
|
||||
long count; // 当前队列中的数量
|
||||
long cpu_exec_proc_jiffies; // 进程可执行的时间片数量
|
||||
struct process_control_block proc_queue;
|
||||
};
|
||||
|
||||
|
||||
extern struct sched_queue_t sched_cfs_ready_queue[MAX_CPU_NUM]; // 就绪队列
|
||||
|
||||
/**
|
||||
* @brief 调度函数
|
||||
*
|
||||
*/
|
||||
void sched_cfs();
|
||||
|
||||
/**
|
||||
* @brief 包裹sched_cfs(),调度函数
|
||||
*
|
||||
*/
|
||||
void sched();
|
||||
|
||||
/**
|
||||
* @brief 将PCB加入就绪队列
|
||||
*
|
||||
* @param pcb
|
||||
*/
|
||||
void sched_cfs_enqueue(struct process_control_block *pcb);
|
||||
|
||||
/**
|
||||
* @brief 包裹sched_enqueue(),将PCB加入就绪队列
|
||||
*
|
||||
*
|
||||
* @param pcb
|
||||
*/
|
||||
void sched_enqueue(struct process_control_block *pcb);
|
||||
|
||||
/**
|
||||
* @brief 从就绪队列中取出PCB
|
||||
* @brief 包裹sched_cfs(),调度函数
|
||||
*
|
||||
* @return struct process_control_block*
|
||||
*/
|
||||
struct process_control_block *sched_cfs_dequeue();
|
||||
void sched();
|
||||
|
||||
|
||||
/**
|
||||
* @brief 初始化进程调度器
|
||||
*
|
||||
*/
|
||||
void sched_init();
|
||||
|
||||
/**
|
||||
* @brief 当时钟中断到达时,更新时间片
|
||||
*
|
||||
*
|
||||
*/
|
||||
void sched_update_jiffies();
|
||||
|
||||
void sched_update_jiffies();
|
@ -6,8 +6,8 @@ all: apu_boot.o smp.o
|
||||
|
||||
|
||||
apu_boot.o: apu_boot.S
|
||||
gcc -E apu_boot.S > _apu_boot.s # 预处理
|
||||
$(CC) -E apu_boot.S > _apu_boot.s # 预处理
|
||||
as $(ASFLAGS) -o apu_boot.o _apu_boot.s
|
||||
|
||||
smp.o: smp.c
|
||||
gcc $(CFLAGS) -c smp.c -o smp.o
|
||||
$(CC) $(CFLAGS) -c smp.c -o smp.o
|
@ -5,4 +5,4 @@ CFLAGS += -I .
|
||||
all: syscall.o
|
||||
|
||||
syscall.o: syscall.c
|
||||
gcc $(CFLAGS) -c syscall.c -o syscall.o
|
||||
$(CC) $(CFLAGS) -c syscall.c -o syscall.o
|
||||
|
@ -4,10 +4,10 @@ all: timer.o sleep.o
|
||||
CFLAGS += -I .
|
||||
|
||||
timer.o: timer.c
|
||||
gcc $(CFLAGS) -c timer.c -o timer.o
|
||||
$(CC) $(CFLAGS) -c timer.c -o timer.o
|
||||
|
||||
sleep.o: sleep.c
|
||||
gcc $(CFLAGS) -c sleep.c -o sleep.o
|
||||
$(CC) $(CFLAGS) -c sleep.c -o sleep.o
|
||||
|
||||
clean:
|
||||
echo "Done."
|
@ -4,4 +4,4 @@ all: about.o
|
||||
|
||||
objcopy -I elf64-x86-64 -R ".eh_frame" -R ".comment" -O elf64-x86-64 $(tmp_output_dir)/about $(output_dir)/about.elf
|
||||
about.o: about.c
|
||||
gcc $(CFLAGS) -c about.c -o about.o
|
||||
$(CC) $(CFLAGS) -c about.c -o about.o
|
||||
|
@ -4,13 +4,13 @@ all: shell.o cmd.o cmd_help.o cmd_test.o
|
||||
|
||||
objcopy -I elf64-x86-64 -R ".eh_frame" -R ".comment" -O elf64-x86-64 $(tmp_output_dir)/shell $(output_dir)/shell.elf
|
||||
shell.o: shell.c
|
||||
gcc $(CFLAGS) -c shell.c -o shell.o
|
||||
$(CC) $(CFLAGS) -c shell.c -o shell.o
|
||||
|
||||
cmd.o: cmd.c
|
||||
gcc $(CFLAGS) -c cmd.c -o cmd.o
|
||||
$(CC) $(CFLAGS) -c cmd.c -o cmd.o
|
||||
|
||||
cmd_test.o: cmd_test.c
|
||||
gcc $(CFLAGS) -c cmd_test.c -o cmd_test.o
|
||||
$(CC) $(CFLAGS) -c cmd_test.c -o cmd_test.o
|
||||
|
||||
cmd_help.o: cmd_help.c
|
||||
gcc $(CFLAGS) -c cmd_help.c -o cmd_help.o
|
||||
$(CC) $(CFLAGS) -c cmd_help.c -o cmd_help.o
|
||||
|
@ -1,12 +1,13 @@
|
||||
#include <libc/unistd.h>
|
||||
#include <libc/stdio.h>
|
||||
#include <libc/fcntl.h>
|
||||
#include <libc/stdlib.h>
|
||||
#include <libKeyboard/keyboard.h>
|
||||
#include <libc/string.h>
|
||||
#include <libc/stddef.h>
|
||||
#include <libc/sys/stat.h>
|
||||
#include "cmd.h"
|
||||
#include <libKeyboard/keyboard.h>
|
||||
#include <libc/fcntl.h>
|
||||
#include <libc/printf.h>
|
||||
#include <libc/stddef.h>
|
||||
#include <libc/stdio.h>
|
||||
#include <libc/stdlib.h>
|
||||
#include <libc/string.h>
|
||||
#include <libc/sys/stat.h>
|
||||
#include <libc/unistd.h>
|
||||
|
||||
#define pause_cpu() asm volatile("pause\n\t");
|
||||
#define MEM_HISTORY 1024
|
||||
@ -50,11 +51,14 @@ void main_loop(int kb_fd)
|
||||
{
|
||||
int argc = 0;
|
||||
char **argv;
|
||||
|
||||
|
||||
printf("[DragonOS] %s # ", shell_current_path);
|
||||
|
||||
|
||||
memset(input_buffer, 0, INPUT_BUFFER_SIZE);
|
||||
|
||||
//添加初始光标
|
||||
put_string(" ", COLOR_BLACK, COLOR_WHITE);
|
||||
|
||||
// 循环读取每一行到buffer
|
||||
count_history++;
|
||||
int count = shell_readline(kb_fd, input_buffer);
|
||||
@ -125,6 +129,7 @@ void change_command(char *buf, int type)
|
||||
current_command_index = count_history - 2;
|
||||
strcpy(buf, history_commands[current_command_index]);
|
||||
printf("%s", buf);
|
||||
put_string(" ", COLOR_BLACK, COLOR_WHITE);
|
||||
}
|
||||
/**
|
||||
* @brief 循环读取每一行
|
||||
@ -143,6 +148,8 @@ int shell_readline(int fd, char *buf)
|
||||
//向上方向键
|
||||
if (count_history != 0 && key == 0xc8)
|
||||
{
|
||||
// put_string(" ", COLOR_WHITE, COLOR_BLACK);
|
||||
printf("%c", '\b');
|
||||
clear_command(count, buf);
|
||||
count = 0;
|
||||
//向历史
|
||||
@ -152,6 +159,8 @@ int shell_readline(int fd, char *buf)
|
||||
//向下方向键
|
||||
if (count_history != 0 && key == 0x50)
|
||||
{
|
||||
// put_string(" ", COLOR_WHITE, COLOR_BLACK);
|
||||
printf("%c", '\b');
|
||||
clear_command(count, buf);
|
||||
count = 0;
|
||||
//向现在
|
||||
@ -162,9 +171,11 @@ int shell_readline(int fd, char *buf)
|
||||
{
|
||||
if (count > 0 && current_command_index >= count_history)
|
||||
{
|
||||
memset(history_commands[current_command_index - 1], 0, sizeof(history_commands[current_command_index - 1]));
|
||||
memset(history_commands[current_command_index - 1], 0,
|
||||
sizeof(history_commands[current_command_index - 1]));
|
||||
count_history--;
|
||||
}
|
||||
printf("%c", '\b');
|
||||
return count;
|
||||
}
|
||||
|
||||
@ -174,14 +185,22 @@ int shell_readline(int fd, char *buf)
|
||||
{
|
||||
if (count > 0)
|
||||
{
|
||||
buf[--count] = 0;
|
||||
// 回退去除先前光标
|
||||
printf("%c", '\b');
|
||||
// 去除字符
|
||||
printf("%c", '\b');
|
||||
buf[--count] = 0;
|
||||
// 在最后一个字符处加光标
|
||||
put_string(" ", COLOR_BLACK, COLOR_WHITE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("%c", '\b');
|
||||
buf[count++] = key;
|
||||
printf("%c", key);
|
||||
// 在最后一个字符处加光标
|
||||
put_string(" ", COLOR_BLACK, COLOR_WHITE);
|
||||
}
|
||||
if (count > 0 && current_command_index >= count_history)
|
||||
{
|
||||
@ -197,7 +216,10 @@ int shell_readline(int fd, char *buf)
|
||||
|
||||
// 输入缓冲区满了之后,直接返回
|
||||
if (count >= INPUT_BUFFER_SIZE - 1)
|
||||
{
|
||||
printf("%c", '\b');
|
||||
return count;
|
||||
}
|
||||
|
||||
pause_cpu();
|
||||
}
|
||||
|
@ -4,4 +4,4 @@ CFLAGS += -I .
|
||||
|
||||
|
||||
keyboard.o: keyboard.c
|
||||
gcc $(CFLAGS) -c keyboard.c -o keyboard.o
|
||||
$(CC) $(CFLAGS) -c keyboard.c -o keyboard.o
|
@ -18,31 +18,31 @@ libc: unistd.o fcntl.o malloc.o errno.o printf.o stdlib.o ctype.o string.o diren
|
||||
done
|
||||
|
||||
unistd.o: unistd.c
|
||||
gcc $(CFLAGS) -c unistd.c -o unistd.o
|
||||
$(CC) $(CFLAGS) -c unistd.c -o unistd.o
|
||||
|
||||
fcntl.o: fcntl.c
|
||||
gcc $(CFLAGS) -c fcntl.c -o fcntl.o
|
||||
$(CC) $(CFLAGS) -c fcntl.c -o fcntl.o
|
||||
|
||||
malloc.o: malloc.c
|
||||
gcc $(CFLAGS) -c malloc.c -o malloc.o
|
||||
$(CC) $(CFLAGS) -c malloc.c -o malloc.o
|
||||
|
||||
errno.o: errno.c
|
||||
gcc $(CFLAGS) -c errno.c -o errno.o
|
||||
$(CC) $(CFLAGS) -c errno.c -o errno.o
|
||||
|
||||
printf.o: printf.c
|
||||
gcc $(CFLAGS) -c printf.c -o printf.o
|
||||
$(CC) $(CFLAGS) -c printf.c -o printf.o
|
||||
|
||||
stdlib.o: stdlib.c
|
||||
gcc $(CFLAGS) -c stdlib.c -o stdlib.o
|
||||
$(CC) $(CFLAGS) -c stdlib.c -o stdlib.o
|
||||
|
||||
ctype.o: ctype.c
|
||||
gcc $(CFLAGS) -c ctype.c -o ctype.o
|
||||
$(CC) $(CFLAGS) -c ctype.c -o ctype.o
|
||||
|
||||
string.o: string.c
|
||||
gcc $(CFLAGS) -c string.c -o string.o
|
||||
$(CC) $(CFLAGS) -c string.c -o string.o
|
||||
|
||||
dirent.o: dirent.c
|
||||
gcc $(CFLAGS) -c dirent.c -o dirent.o
|
||||
$(CC) $(CFLAGS) -c dirent.c -o dirent.o
|
||||
|
||||
time.o: time.c
|
||||
gcc $(CFLAGS) -c time.c -o time.o
|
||||
$(CC) $(CFLAGS) -c time.c -o time.o
|
@ -5,10 +5,10 @@ CFLAGS += -I .
|
||||
all: fabs.o round.o pow.o
|
||||
|
||||
fabs.o: fabs.c
|
||||
gcc $(CFLAGS) -c fabs.c -o fabs.o
|
||||
$(CC) $(CFLAGS) -c fabs.c -o fabs.o
|
||||
|
||||
round.o: round.c
|
||||
gcc $(CFLAGS) -c round.c -o round.o
|
||||
$(CC) $(CFLAGS) -c round.c -o round.o
|
||||
|
||||
pow.o: pow.c
|
||||
gcc $(CFLAGS) -c pow.c -o pow.o
|
||||
$(CC) $(CFLAGS) -c pow.c -o pow.o
|
@ -5,7 +5,7 @@ CFLAGS += -I .
|
||||
|
||||
|
||||
wait.o: wait.c
|
||||
gcc $(CFLAGS) -c wait.c -o wait.o
|
||||
$(CC) $(CFLAGS) -c wait.c -o wait.o
|
||||
|
||||
stat.o: stat.c
|
||||
gcc $(CFLAGS) -c stat.c -o stat.o
|
||||
$(CC) $(CFLAGS) -c stat.c -o stat.o
|
@ -4,7 +4,7 @@ all: start.o
|
||||
|
||||
ifeq ($(ARCH), __x86_64__)
|
||||
start.o:
|
||||
gcc $(CFLAGS) -c elf/start.c -o elf/start.o
|
||||
$(CC) $(CFLAGS) -c elf/start.c -o elf/start.o
|
||||
endif
|
||||
|
||||
clean:
|
||||
|
@ -5,4 +5,4 @@ all: libsystem
|
||||
libsystem: syscall.o
|
||||
|
||||
syscall.o: syscall.c
|
||||
gcc $(CFLAGS) -c syscall.c -o syscall.o
|
||||
$(CC) $(CFLAGS) -c syscall.c -o syscall.o
|
||||
|
Loading…
x
Reference in New Issue
Block a user