mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-08 18:26:48 +00:00
改用int250作为系统调用
This commit is contained in:
parent
011246281a
commit
2d7b2b7048
@ -28,8 +28,7 @@ int printk_init(const int char_size_x, const int char_size_y)
|
||||
struct multiboot_tag_framebuffer_info_t info;
|
||||
int reserved;
|
||||
multiboot2_iter(multiboot2_get_Framebuffer_info, &info, &reserved);
|
||||
|
||||
|
||||
|
||||
pos.width = info.framebuffer_width;
|
||||
pos.height = info.framebuffer_height;
|
||||
|
||||
@ -37,7 +36,7 @@ int printk_init(const int char_size_x, const int char_size_y)
|
||||
pos.char_size_y = char_size_y;
|
||||
pos.max_x = calculate_max_charNum(pos.width, char_size_x);
|
||||
pos.max_y = calculate_max_charNum(pos.height, char_size_y);
|
||||
|
||||
|
||||
VBE_FB_phys_addr = (ul)info.framebuffer_addr;
|
||||
|
||||
pos.FB_address = (uint *)0xffff800003000000;
|
||||
@ -72,11 +71,11 @@ int printk_init(const int char_size_x, const int char_size_y)
|
||||
|
||||
pos.x = 0;
|
||||
pos.y = 0;
|
||||
|
||||
|
||||
cls();
|
||||
|
||||
kdebug("width=%d\theight=%d", pos.width, pos.height);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -440,10 +439,17 @@ static char *write_num(char *str, ul num, int base, int field_width, int precisi
|
||||
pad = (flags & PAD_ZERO) ? '0' : ' ';
|
||||
|
||||
sign = 0;
|
||||
if (flags & SIGN && num < 0)
|
||||
|
||||
if (flags & SIGN)
|
||||
{
|
||||
sign = '-';
|
||||
num = -num;
|
||||
int64_t signed_num = (int64_t)num;
|
||||
if (signed_num < 0)
|
||||
{
|
||||
sign = '-';
|
||||
num = -signed_num;
|
||||
}
|
||||
else
|
||||
num = signed_num;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -653,7 +659,7 @@ int printk_color(unsigned int FRcolor, unsigned int BKcolor, const char *fmt, ..
|
||||
* @param BKcolor 背景色
|
||||
* @param ... 格式化字符串
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
if (get_rflags() & 0x200UL)
|
||||
spin_lock(&printk_lock); // 不是中断处理程序调用printk,加锁
|
||||
|
@ -436,7 +436,6 @@ void apic_init()
|
||||
{
|
||||
RCBA_vaddr = 0;
|
||||
kwarn("Cannot get RCBA address. RCBA_phys=%#010lx", RCBA_phys);
|
||||
|
||||
}
|
||||
sti();
|
||||
}
|
||||
@ -448,50 +447,60 @@ void apic_init()
|
||||
*/
|
||||
void do_IRQ(struct pt_regs *rsp, ul number)
|
||||
{
|
||||
switch (number & 0x80) // 以0x80为界限,低于0x80的是外部中断控制器,高于0x80的是Local APIC
|
||||
|
||||
if (number < 0x80) // 以0x80为界限,低于0x80的是外部中断控制器,高于0x80的是Local APIC
|
||||
|
||||
// 外部中断控制器
|
||||
{
|
||||
case 0x00: // 外部中断控制器
|
||||
/* code */
|
||||
irq_desc_t *irq = &interrupt_desc[number - 32];
|
||||
|
||||
// 执行中断上半部处理程序
|
||||
if (irq->handler != NULL)
|
||||
irq->handler(number, irq->parameter, rsp);
|
||||
else
|
||||
kwarn("Intr vector [%d] does not have a handler!");
|
||||
|
||||
// 向中断控制器发送应答消息
|
||||
if (irq->controller != NULL && irq->controller->ack != NULL)
|
||||
irq->controller->ack(number);
|
||||
else
|
||||
{
|
||||
irq_desc_t *irq = &interrupt_desc[number - 32];
|
||||
|
||||
// 执行中断上半部处理程序
|
||||
if (irq->handler != NULL)
|
||||
irq->handler(number, irq->parameter, rsp);
|
||||
else
|
||||
kwarn("Intr vector [%d] does not have a handler!");
|
||||
|
||||
// 向中断控制器发送应答消息
|
||||
if (irq->controller != NULL && irq->controller->ack != NULL)
|
||||
irq->controller->ack(number);
|
||||
else
|
||||
{
|
||||
|
||||
// 向EOI寄存器写入0x00表示结束中断
|
||||
__asm__ __volatile__("movq $0x00, %%rdx \n\t"
|
||||
"movq $0x00, %%rax \n\t"
|
||||
"movq $0x80b, %%rcx \n\t"
|
||||
"wrmsr \n\t" ::
|
||||
: "memory");
|
||||
}
|
||||
// 向EOI寄存器写入0x00表示结束中断
|
||||
__asm__ __volatile__("movq $0x00, %%rdx \n\t"
|
||||
"movq $0x00, %%rax \n\t"
|
||||
"movq $0x80b, %%rcx \n\t"
|
||||
"wrmsr \n\t" ::
|
||||
: "memory");
|
||||
}
|
||||
break;
|
||||
case 0x80:
|
||||
}
|
||||
|
||||
else if (number >= 0x80 && number != 250)
|
||||
|
||||
{
|
||||
printk_color(RED, BLACK, "SMP IPI [ %d ]\n", number);
|
||||
apic_local_apic_edge_ack(number);
|
||||
default:
|
||||
}
|
||||
else if (number == 250) // 系统调用
|
||||
{
|
||||
kdebug("receive syscall");
|
||||
kdebug("rflags=%#010lx", rsp->rflags);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
|
||||
kwarn("do IRQ receive: %d", number);
|
||||
break;
|
||||
}
|
||||
|
||||
// 检测是否有未处理的软中断
|
||||
if (softirq_status != 0)
|
||||
do_softirq();
|
||||
|
||||
// 检测当前进程是否可被调度
|
||||
struct process_control_block *current_proc = get_current_pcb();
|
||||
if (current_proc->flags & PROC_NEED_SCHED)
|
||||
if (current_pcb->flags & PROC_NEED_SCHED)
|
||||
{
|
||||
sched_cfs();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -50,6 +50,7 @@ hardware_intr_controller HPET_intr_controller =
|
||||
|
||||
void HPET_handler(uint64_t number, uint64_t param, struct pt_regs *regs)
|
||||
{
|
||||
printk("(HPET)");
|
||||
switch (param)
|
||||
{
|
||||
case 0: // 定时器0中断
|
||||
@ -73,7 +74,10 @@ void HPET_handler(uint64_t number, uint64_t param, struct pt_regs *regs)
|
||||
}
|
||||
|
||||
if (sched_cfs_ready_queue.cpu_exec_proc_jiffies <= 0)
|
||||
{
|
||||
current_pcb->flags |= PROC_NEED_SCHED;
|
||||
kdebug("need_sched. proc_jiffies=%ld", sched_cfs_ready_queue.cpu_exec_proc_jiffies);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
@ -138,7 +142,7 @@ int HPET_init()
|
||||
// 由于这段内存与io/apic的映射在同一物理页内,因此不需要重复映射
|
||||
HPET_REG_BASE = SPECIAL_MEMOEY_MAPPING_VIRT_ADDR_BASE + hpet_table->address;
|
||||
}
|
||||
|
||||
|
||||
// 读取计时精度并计算频率
|
||||
uint64_t tmp;
|
||||
tmp = *(uint64_t *)(HPET_REG_BASE + GCAP_ID);
|
||||
@ -152,18 +156,22 @@ int HPET_init()
|
||||
// 使用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);
|
||||
|
||||
*(uint64_t *)(HPET_REG_BASE + GEN_CONF) = 3; // 置位旧设备中断路由兼容标志位、定时器组使能标志位
|
||||
io_mfence();
|
||||
|
||||
|
||||
*(uint64_t *)(HPET_REG_BASE + MAIN_CNT) = 0;
|
||||
io_mfence();
|
||||
*(uint64_t *)(HPET_REG_BASE + TIM0_CONF) = 0x004c; // 设置定时器0为周期定时,边沿触发,投递到IO APIC的2号引脚(这里有点绕,写的是8259的引脚号,但是因为禁用了8259,因此会被路由到IO APIC的2号引脚)
|
||||
io_mfence();
|
||||
*(uint64_t *)(HPET_REG_BASE + TIM0_COMP) = HPET_freq; // 1s触发一次中断
|
||||
io_mfence();
|
||||
|
||||
rtc_get_cmos_time(&rtc_now);
|
||||
*(uint64_t *)(HPET_REG_BASE + MAIN_CNT) = 0;
|
||||
|
||||
|
||||
|
||||
kinfo("HPET Initialized.");
|
||||
*(uint64_t *)(HPET_REG_BASE + GEN_CONF) = 3; // 置位旧设备中断路由兼容标志位、定时器组使能标志位
|
||||
io_mfence();
|
||||
// 注册中断
|
||||
irq_register(34, &entry, &HPET_handler, 0, &HPET_intr_controller, "HPET0");
|
||||
kinfo("HPET Initialized.");
|
||||
}
|
@ -22,7 +22,7 @@ enum CMOSTimeSelector
|
||||
int rtc_get_cmos_time(struct rtc_time_t *t)
|
||||
{
|
||||
// 为防止中断请求打断该过程,需要先关中断
|
||||
//cli();
|
||||
cli();
|
||||
|
||||
uint8_t status_register_B = read_cmos(0x0B); // 读取状态寄存器B
|
||||
bool is_24h = ((status_register_B & 0x02) ? true : false); // 判断是否启用24小时模式
|
||||
@ -53,6 +53,6 @@ int rtc_get_cmos_time(struct rtc_time_t *t)
|
||||
|
||||
if ((!is_24h) && t->hour & 0x80) // 将十二小时制转为24小时
|
||||
t->hour = ((t->hour & 0x7f) + 12) % 24;
|
||||
//sti();
|
||||
sti();
|
||||
return 0;
|
||||
}
|
||||
|
@ -52,6 +52,7 @@ Restore_all:
|
||||
|
||||
popq %rax
|
||||
addq $0x10, %rsp // 弹出变量FUNC和errcode
|
||||
|
||||
iretq
|
||||
|
||||
ret_from_exception:
|
||||
@ -106,9 +107,6 @@ Err_Code:
|
||||
ENTRY(system_call)
|
||||
|
||||
// 由于sysenter指令会禁用中断,因此要在这里手动开启中断
|
||||
sti;
|
||||
|
||||
|
||||
subq $0x38, %rsp
|
||||
|
||||
cld;
|
||||
@ -146,6 +144,7 @@ ENTRY(system_call)
|
||||
|
||||
// 从系统调用中返回
|
||||
ENTRY(ret_from_system_call)
|
||||
|
||||
movq %rax, 0x80(%rsp) // 将当前rax的值先存到栈中rax的位置
|
||||
|
||||
|
||||
@ -168,9 +167,10 @@ ENTRY(ret_from_system_call)
|
||||
popq %rax
|
||||
movq %rax, %es
|
||||
popq %rax
|
||||
addq $0x38, %rsp
|
||||
.byte 0x48
|
||||
addq $0x38, %rsp
|
||||
.byte 0x48
|
||||
sysexit
|
||||
|
||||
|
||||
|
||||
// 0 #DE 除法错误
|
||||
@ -337,6 +337,15 @@ ENTRY(virtualization_exception)
|
||||
xchgq %rax, (%rsp) // 把FUNC的地址换入栈中
|
||||
jmp Err_Code
|
||||
|
||||
/*
|
||||
// 0x80 系统调用门
|
||||
ENTRY(syscall_int)
|
||||
pushq $0
|
||||
pushq %rax
|
||||
leaq do_syscall_int(%rip), %rax // 获取系统调用服务程序的地址
|
||||
xchgq %rax, (%rsp) // 把FUNC的地址换入栈中
|
||||
jmp Err_Code
|
||||
*/
|
||||
|
||||
ENTRY(_stack_start)
|
||||
.quad initial_proc_union + 32768
|
@ -129,6 +129,8 @@ Build_IRQ(0xcf);
|
||||
Build_IRQ(0xd0);
|
||||
Build_IRQ(0xd1);
|
||||
|
||||
Build_IRQ(0xfa); // 系统调用入口
|
||||
void (*syscall_intr_table[1])(void) = {IRQ0xfainterrupt};
|
||||
// 初始化IPI中断服务程序数组
|
||||
void (*SMP_interrupt_table[SMP_IRQ_NUM])(void) =
|
||||
{
|
||||
|
@ -22,6 +22,8 @@ extern void do_IRQ(struct pt_regs *regs, ul number);
|
||||
|
||||
extern void (*SMP_interrupt_table[SMP_IRQ_NUM])(void);
|
||||
|
||||
extern void (*syscall_intr_table[1])(void);
|
||||
|
||||
/* ========= 中断向量分配表 ==========
|
||||
|
||||
0~255 IDT
|
||||
|
@ -52,7 +52,7 @@ void do_softirq()
|
||||
}
|
||||
}
|
||||
|
||||
cli();
|
||||
|
||||
}
|
||||
|
||||
void softirq_init()
|
||||
|
@ -196,7 +196,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long error_code)
|
||||
unsigned long cr2 = 0;
|
||||
|
||||
__asm__ __volatile__("movq %%cr2, %0":"=r"(cr2)::"memory");
|
||||
|
||||
hlt();
|
||||
kerror("do_page_fault(14),Error code :%#018lx,RSP:%#018lx,RIP:%#018lx\n",error_code , regs->rsp , regs->rip);
|
||||
|
||||
if(!(error_code & 0x01))
|
||||
@ -284,8 +284,6 @@ void do_virtualization_exception(struct pt_regs *regs, unsigned long error_code)
|
||||
|
||||
void sys_vector_init()
|
||||
{
|
||||
kdebug("do_divide_error=%#018lx", do_divide_error);
|
||||
kdebug("&do_divide_error=%#018lx", &do_divide_error);
|
||||
set_trap_gate(0, 1, divide_error);
|
||||
set_trap_gate(1, 1, debug);
|
||||
set_intr_gate(2, 1, nmi);
|
||||
@ -308,6 +306,8 @@ void sys_vector_init()
|
||||
set_trap_gate(19, 1, SIMD_exception);
|
||||
set_trap_gate(20, 1, virtualization_exception);
|
||||
// 中断号21-31由Intel保留,不能使用
|
||||
|
||||
|
||||
|
||||
// 32-255为用户自定义中断内部
|
||||
|
||||
|
@ -48,4 +48,5 @@ void machine_check();
|
||||
void SIMD_exception();
|
||||
void virtualization_exception();
|
||||
|
||||
void syscall_int(); // 系统调用门
|
||||
void sys_vector_init();
|
@ -212,6 +212,7 @@ void system_initialize()
|
||||
syscall_init();
|
||||
// 再初始化进程模块。顺序不能调转
|
||||
sched_init();
|
||||
kdebug("sched_cfs_ready_queue.cpu_exec_proc_jiffies=%ld", sched_cfs_ready_queue.cpu_exec_proc_jiffies);
|
||||
timer_init();
|
||||
|
||||
smp_init();
|
||||
@ -223,10 +224,14 @@ void system_initialize()
|
||||
ahci_init();
|
||||
// test_slab();
|
||||
// test_mm();
|
||||
|
||||
|
||||
process_init();
|
||||
cli();
|
||||
|
||||
HPET_init();
|
||||
sti();
|
||||
|
||||
|
||||
while(1);
|
||||
}
|
||||
|
||||
//操作系统内核从这里开始执行
|
||||
|
@ -32,12 +32,12 @@ 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));
|
||||
wrmsr(0x175, next->thread->rbp);
|
||||
|
||||
kdebug("next=%#018lx", next);
|
||||
kdebug("initial_tss[0].rsp1=%#018lx", initial_tss[0].rsp1);
|
||||
kdebug("prev->thread->rsp0:%#018lx\n", prev->thread->rbp);
|
||||
kdebug("next->thread->rsp0:%#018lx\n", next->thread->rbp);
|
||||
kdebug("next->thread->rip:%#018lx\n", next->thread->rip);
|
||||
|
||||
// kdebug("next=%#018lx", next);
|
||||
// kdebug("initial_tss[0].rsp1=%#018lx", initial_tss[0].rsp1);
|
||||
// kdebug("prev->thread->rsp0:%#018lx\n", prev->thread->rbp);
|
||||
// kdebug("next->thread->rsp0:%#018lx\n", next->thread->rbp);
|
||||
// kdebug("next->thread->rip:%#018lx\n", next->thread->rip);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -51,20 +51,35 @@ void user_level_function()
|
||||
// enter_syscall(15, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
|
||||
// enter_syscall(SYS_PRINTF, (ul) "test_sys_printf\n", 0, 0, 0, 0, 0, 0, 0);
|
||||
|
||||
//while(1);
|
||||
long ret = 0;
|
||||
// color_printk(RED,BLACK,"user_level_function task is running\n");
|
||||
while(1);
|
||||
|
||||
char string[] = "Hello World!\n";
|
||||
|
||||
/*
|
||||
__asm__ __volatile__("leaq sysexit_return_address(%%rip), %%rdx \n\t"
|
||||
"movq %%rsp, %%rcx \n\t"
|
||||
"sysenter \n\t"
|
||||
"sysexit_return_address: \n\t"
|
||||
: "=a"(ret)
|
||||
: "0"(1), "D"(string)
|
||||
: "memory", "rcx", "rdx", "r14");
|
||||
// kinfo("Return from syscall id 15...");
|
||||
: "memory");
|
||||
*/
|
||||
|
||||
for (int i = 0; i < 10; ++i)
|
||||
{
|
||||
long err_code;
|
||||
ul addr = (ul)string;
|
||||
__asm__ __volatile__(
|
||||
"movq %2, %%r8 \n\t"
|
||||
"int $250 \n\t"
|
||||
: "=a"(err_code)
|
||||
: "a"(SYS_PRINTF), "m"(addr)
|
||||
: "memory", "r8");
|
||||
}
|
||||
// enter_syscall_int(SYS_PRINTF, (ul) "test_sys_printf\n", 0, 0, 0, 0, 0, 0, 0);
|
||||
// kinfo("Return from syscall id 15...");
|
||||
|
||||
while (1)
|
||||
;
|
||||
@ -85,7 +100,7 @@ ul do_execve(struct pt_regs *regs)
|
||||
regs->ds = 0;
|
||||
regs->es = 0;
|
||||
|
||||
kdebug("do_execve is running...");
|
||||
// kdebug("do_execve is running...");
|
||||
|
||||
// 映射起始页面
|
||||
// mm_map_proc_page_table(get_CR3(), true, 0x800000, alloc_pages(ZONE_NORMAL, 1, PAGE_PGT_MAPPED)->addr_phys, PAGE_2M_SIZE, PAGE_USER_PAGE, true);
|
||||
@ -114,7 +129,9 @@ ul do_execve(struct pt_regs *regs)
|
||||
current_pcb->addr_limit = KERNEL_BASE_LINEAR_ADDR;
|
||||
// 将程序代码拷贝到对应的内存中
|
||||
memcpy((void *)0x800000, user_level_function, 1024);
|
||||
kdebug("program copied!");
|
||||
|
||||
|
||||
// kdebug("program copied!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -126,7 +143,7 @@ ul do_execve(struct pt_regs *regs)
|
||||
*/
|
||||
ul initial_kernel_thread(ul arg)
|
||||
{
|
||||
kinfo("initial proc running...\targ:%#018lx", arg);
|
||||
// kinfo("initial proc running...\targ:%#018lx", arg);
|
||||
|
||||
struct pt_regs *regs;
|
||||
|
||||
@ -136,7 +153,7 @@ ul initial_kernel_thread(ul arg)
|
||||
// memset((void*)current_pcb->mm->pgd, 0, PAGE_4K_SIZE);
|
||||
|
||||
regs = (struct pt_regs *)current_pcb->thread->rsp;
|
||||
kdebug("current_pcb->thread->rsp=%#018lx", current_pcb->thread->rsp);
|
||||
// kdebug("current_pcb->thread->rsp=%#018lx", current_pcb->thread->rsp);
|
||||
current_pcb->flags = 0;
|
||||
// 将返回用户层的代码压入堆栈,向rdx传入regs的地址,然后jmp到do_execve这个系统调用api的处理函数 这里的设计思路和switch_proc类似
|
||||
__asm__ __volatile__("movq %1, %%rsp \n\t"
|
||||
@ -226,8 +243,8 @@ int kernel_thread(unsigned long (*fn)(unsigned long), unsigned long arg, unsigne
|
||||
|
||||
// rip寄存器指向内核线程的引导程序
|
||||
regs.rip = (ul)kernel_thread_func;
|
||||
kdebug("kernel_thread_func=%#018lx", kernel_thread_func);
|
||||
kdebug("&kernel_thread_func=%#018lx", &kernel_thread_func);
|
||||
// kdebug("kernel_thread_func=%#018lx", kernel_thread_func);
|
||||
// kdebug("&kernel_thread_func=%#018lx", &kernel_thread_func);
|
||||
|
||||
return do_fork(®s, flags, 0, 0);
|
||||
}
|
||||
@ -277,7 +294,7 @@ void process_init()
|
||||
initial_proc_union.pcb.state = PROC_RUNNING;
|
||||
|
||||
// 获取新的进程的pcb
|
||||
// struct process_control_block *p = container_of(list_next(¤t_pcb->list), struct process_control_block, list);
|
||||
struct process_control_block *p = container_of(list_next(¤t_pcb->list), struct process_control_block, list);
|
||||
|
||||
kdebug("Ready to switch...");
|
||||
// 切换到新的内核线程
|
||||
@ -317,12 +334,13 @@ unsigned long do_fork(struct pt_regs *regs, unsigned long clone_flags, unsigned
|
||||
tsk->priority = 2;
|
||||
++(tsk->pid);
|
||||
tsk->state = PROC_UNINTERRUPTIBLE;
|
||||
list_init(&tsk->list);
|
||||
list_add(&initial_proc_union.pcb.list, &tsk->list);
|
||||
|
||||
// 将线程结构体放置在pcb的后面
|
||||
struct thread_struct *thd = (struct thread_struct *)(tsk + 1);
|
||||
memset(thd, 0, sizeof(struct thread_struct));
|
||||
tsk->thread = thd;
|
||||
|
||||
// 将寄存器信息存储到进程的内核栈空间的顶部
|
||||
memcpy((void *)((ul)tsk + STACK_SIZE - sizeof(struct pt_regs)), regs, sizeof(struct pt_regs));
|
||||
|
||||
@ -333,7 +351,6 @@ unsigned long do_fork(struct pt_regs *regs, unsigned long clone_flags, unsigned
|
||||
thd->fs = KERNEL_DS;
|
||||
thd->gs = KERNEL_DS;
|
||||
|
||||
|
||||
kdebug("do_fork() thd->rsp=%#018lx", thd->rsp);
|
||||
// 若进程不是内核层的进程,则跳转到ret from system call
|
||||
if (!(tsk->flags & PF_KTHREAD))
|
||||
|
@ -10,6 +10,7 @@ struct process_control_block *sched_cfs_dequeue()
|
||||
{
|
||||
if (list_empty(&sched_cfs_ready_queue.proc_queue.list))
|
||||
{
|
||||
kdebug("list empty");
|
||||
return &initial_proc_union.pcb;
|
||||
}
|
||||
|
||||
@ -17,6 +18,7 @@ struct process_control_block *sched_cfs_dequeue()
|
||||
|
||||
list_del(&proc->list);
|
||||
--sched_cfs_ready_queue.count;
|
||||
kdebug("dequeued");
|
||||
return proc;
|
||||
}
|
||||
|
||||
@ -30,7 +32,7 @@ void sched_cfs_enqueue(struct process_control_block *pcb)
|
||||
struct process_control_block *proc = container_of(list_next(&sched_cfs_ready_queue.proc_queue.list), struct process_control_block, list);
|
||||
if (proc == &initial_proc_union.pcb)
|
||||
return;
|
||||
if (!(list_empty(&sched_cfs_ready_queue.proc_queue.list)))
|
||||
if ((list_empty(&sched_cfs_ready_queue.proc_queue.list)) == 0)
|
||||
{
|
||||
while (proc->virtual_runtime < pcb->virtual_runtime)
|
||||
{
|
||||
@ -39,6 +41,7 @@ void sched_cfs_enqueue(struct process_control_block *pcb)
|
||||
}
|
||||
list_append(&proc->list, &pcb->list);
|
||||
++sched_cfs_ready_queue.count;
|
||||
kdebug("enqueued");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -57,7 +60,7 @@ void sched_cfs()
|
||||
if (current_pcb->state = PROC_RUNNING) // 本次切换由于时间片到期引发,则再次加入就绪队列,否则交由其它功能模块进行管理
|
||||
sched_cfs_enqueue(current_pcb);
|
||||
|
||||
if (!sched_cfs_ready_queue.cpu_exec_proc_jiffies)
|
||||
if (sched_cfs_ready_queue.cpu_exec_proc_jiffies <= 0)
|
||||
{
|
||||
switch (proc->priority)
|
||||
{
|
||||
@ -67,7 +70,6 @@ void sched_cfs()
|
||||
break;
|
||||
case 2:
|
||||
default:
|
||||
|
||||
sched_cfs_ready_queue.cpu_exec_proc_jiffies = (4 / sched_cfs_ready_queue.count) << 2;
|
||||
break;
|
||||
}
|
||||
@ -77,24 +79,26 @@ void sched_cfs()
|
||||
}
|
||||
else // 不进行切换
|
||||
{
|
||||
kdebug("not switch.");
|
||||
sched_cfs_enqueue(current_pcb);
|
||||
// kdebug("not switch.");
|
||||
sched_cfs_enqueue(proc);
|
||||
|
||||
if (!sched_cfs_ready_queue.cpu_exec_proc_jiffies)
|
||||
if (sched_cfs_ready_queue.cpu_exec_proc_jiffies <= 0)
|
||||
{
|
||||
switch (proc->priority)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
sched_cfs_ready_queue.cpu_exec_proc_jiffies = 4 / sched_cfs_ready_queue.cpu_exec_proc_jiffies;
|
||||
sched_cfs_ready_queue.cpu_exec_proc_jiffies = 4 / sched_cfs_ready_queue.count;
|
||||
//sched_cfs_ready_queue.cpu_exec_proc_jiffies = 5;
|
||||
break;
|
||||
case 2:
|
||||
default:
|
||||
sched_cfs_ready_queue.cpu_exec_proc_jiffies = (4 / sched_cfs_ready_queue.cpu_exec_proc_jiffies) << 2;
|
||||
//sched_cfs_ready_queue.cpu_exec_proc_jiffies = 5;
|
||||
|
||||
sched_cfs_ready_queue.cpu_exec_proc_jiffies = (4 / sched_cfs_ready_queue.count) << 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
kdebug("hhhh");
|
||||
}
|
||||
}
|
||||
|
||||
@ -107,6 +111,6 @@ void sched_init()
|
||||
memset(&sched_cfs_ready_queue, 0, sizeof(struct sched_queue_t));
|
||||
list_init(&sched_cfs_ready_queue.proc_queue.list);
|
||||
sched_cfs_ready_queue.count = 1; // 因为存在IDLE进程,因此为1
|
||||
sched_cfs_ready_queue.cpu_exec_proc_jiffies = 10;
|
||||
sched_cfs_ready_queue.cpu_exec_proc_jiffies = 15;
|
||||
sched_cfs_ready_queue.proc_queue.virtual_runtime = 0x7fffffffffffffff;
|
||||
}
|
@ -1,11 +1,14 @@
|
||||
#include "syscall.h"
|
||||
#include "../process/process.h"
|
||||
#include <exception/gate.h>
|
||||
#include <exception/irq.h>
|
||||
|
||||
// 导出系统调用入口函数,定义在entry.S中
|
||||
extern void system_call(void);
|
||||
extern void syscall_int(void);
|
||||
|
||||
/**
|
||||
* @brief 系统调用函数,从entry.S中跳转到这里
|
||||
* @brief sysenter的系统调用函数,从entry.S中跳转到这里
|
||||
*
|
||||
* @param regs 3特权级下的寄存器值,rax存储系统调用号
|
||||
* @return ul 对应的系统调用函数的地址
|
||||
@ -22,17 +25,19 @@ ul system_call_function(struct pt_regs *regs)
|
||||
void syscall_init()
|
||||
{
|
||||
kinfo("Initializing syscall...");
|
||||
/*
|
||||
// 向MSR寄存器组中的 IA32_SYSENTER_CS寄存器写入内核的代码段的地址
|
||||
wrmsr(0x174, KERNEL_CS);
|
||||
// 向MSR寄存器组中的 IA32_SYSENTER_ESP寄存器写入内核进程的rbp(在syscall入口中会将rsp减去相应的数值)
|
||||
wrmsr(0x175, current_pcb->thread->rbp);
|
||||
|
||||
|
||||
// 向MSR寄存器组中的 IA32_SYSENTER_EIP寄存器写入系统调用入口的地址。
|
||||
wrmsr(0x176, (ul)system_call);
|
||||
|
||||
*/
|
||||
set_system_trap_gate(250, 0, syscall_intr_table[0]); // 系统调用门
|
||||
}
|
||||
|
||||
/*
|
||||
long enter_syscall(ul syscall_id, ul arg0, ul arg1, ul arg2, ul arg3, ul arg4, ul arg5, ul arg6, ul arg7)
|
||||
{
|
||||
long err_code;
|
||||
@ -53,12 +58,66 @@ long enter_syscall(ul syscall_id, ul arg0, ul arg1, ul arg2, ul arg3, ul arg4, u
|
||||
: "memory", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "rcx", "rdx");
|
||||
return err_code;
|
||||
}
|
||||
*/
|
||||
|
||||
ul enter_syscall_int(ul syscall_id, ul arg0, ul arg1, ul arg2, ul arg3, ul arg4, ul arg5, ul arg6, ul arg7)
|
||||
{
|
||||
long err_code;
|
||||
__asm__ __volatile__(
|
||||
"movq %2, %%r8 \n\t"
|
||||
"movq %3, %%r9 \n\t"
|
||||
"movq %4, %%r10 \n\t"
|
||||
"movq %5, %%r11 \n\t"
|
||||
"movq %6, %%r12 \n\t"
|
||||
"movq %7, %%r13 \n\t"
|
||||
"movq %8, %%r14 \n\t"
|
||||
"movq %9, %%r15 \n\t"
|
||||
"int $0x80 \n\t"
|
||||
: "=a"(err_code)
|
||||
: "a"(syscall_id), "m"(arg0), "m"(arg1), "m"(arg2), "m"(arg3), "m"(arg4), "m"(arg5), "m"(arg6), "m"(arg7)
|
||||
: "memory", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15");
|
||||
return err_code;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 通过中断进入系统调用
|
||||
*
|
||||
* @param syscall_id
|
||||
* @param arg0
|
||||
* @param arg1
|
||||
* @param arg2
|
||||
* @param arg3
|
||||
* @param arg4
|
||||
* @param arg5
|
||||
* @param arg6
|
||||
* @param arg7
|
||||
* @return long
|
||||
*/
|
||||
/*
|
||||
long enter_syscall_int(ul syscall_id, ul arg0, ul arg1, ul arg2, ul arg3, ul arg4, ul arg5, ul arg6, ul arg7)
|
||||
{
|
||||
long err_code;
|
||||
__asm__ __volatile__(
|
||||
"movq %2, %%r8 \n\t"
|
||||
"movq %3, %%r9 \n\t"
|
||||
"movq %4, %%r10 \n\t"
|
||||
"movq %5, %%r11 \n\t"
|
||||
"movq %6, %%r12 \n\t"
|
||||
"movq %7, %%r13 \n\t"
|
||||
"movq %8, %%r14 \n\t"
|
||||
"movq %9, %%r15 \n\t"
|
||||
"int $0x80 \n\t"
|
||||
: "=a"(err_code)
|
||||
: "a"(syscall_id), "m"(arg0), "m"(arg1), "m"(arg2), "m"(arg3), "m"(arg4), "m"(arg5), "m"(arg6), "m"(arg7)
|
||||
: "memory", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "rcx", "rdx");
|
||||
return err_code;
|
||||
}
|
||||
*/
|
||||
/**
|
||||
* @brief 打印字符串的系统调用
|
||||
*
|
||||
*
|
||||
* 当arg1和arg2均为0时,打印黑底白字,否则按照指定的前景色和背景色来打印
|
||||
*
|
||||
*
|
||||
* @param regs 寄存器
|
||||
* @param arg0 要打印的字符串
|
||||
* @param arg1 前景色
|
||||
@ -67,11 +126,20 @@ long enter_syscall(ul syscall_id, ul arg0, ul arg1, ul arg2, ul arg3, ul arg4, u
|
||||
*/
|
||||
ul sys_printf(struct pt_regs *regs)
|
||||
{
|
||||
|
||||
//if(regs->r9 == 0 &®s->r10 == 0)
|
||||
// printk((char*)regs->r8);
|
||||
//else printk_color(regs->r9, regs->r10, (char*)regs->r8);
|
||||
printk_color(BLACK,WHITE,(char *)regs->rdi);
|
||||
|
||||
// if(regs->r9 == 0 &®s->r10 == 0)
|
||||
// printk((char*)regs->r8);
|
||||
// else printk_color(regs->r9, regs->r10, (char*)regs->r8);
|
||||
printk_color(BLACK, WHITE, (char *)regs->r8);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 系统调用的内核入口程序
|
||||
void do_syscall_int(struct pt_regs *regs, unsigned long error_code)
|
||||
{
|
||||
|
||||
ul ret = system_call_table[regs->rax](regs);
|
||||
__asm__ __volatile__("movq %0, %%rax \n\t" ::"r"(ret)
|
||||
: "memory");
|
||||
}
|
@ -9,8 +9,6 @@
|
||||
|
||||
#define ESYSCALL_NOT_EXISTS 1
|
||||
|
||||
|
||||
|
||||
typedef unsigned long (*system_call_t)(struct pt_regs *regs);
|
||||
|
||||
extern void ret_from_system_call(void); // 导出从系统调用返回的函数(定义在entry.S)
|
||||
@ -27,7 +25,8 @@ void syscall_init();
|
||||
* @param syscall_id 系统调用id
|
||||
* @return long 错误码
|
||||
*/
|
||||
long enter_syscall(ul syscall_id,ul arg0, ul arg1, ul arg2, ul arg3, ul arg4, ul arg5, ul arg6, ul arg7);
|
||||
long enter_syscall(ul syscall_id, ul arg0, ul arg1, ul arg2, ul arg3, ul arg4, ul arg5, ul arg6, ul arg7);
|
||||
ul enter_syscall_int(ul syscall_id, ul arg0, ul arg1, ul arg2, ul arg3, ul arg4, ul arg5, ul arg6, ul arg7);
|
||||
|
||||
/**
|
||||
* @brief 系统调用不存在时的处理函数
|
||||
@ -43,9 +42,9 @@ ul system_call_not_exists(struct pt_regs *regs)
|
||||
|
||||
/**
|
||||
* @brief 打印字符串的系统调用
|
||||
*
|
||||
*
|
||||
* 当arg1和arg2均为0时,打印黑底白字,否则按照指定的前景色和背景色来打印
|
||||
*
|
||||
*
|
||||
* @param regs 寄存器
|
||||
* @param arg0 要打印的字符串
|
||||
* @param arg1 前景色
|
||||
@ -54,9 +53,11 @@ ul system_call_not_exists(struct pt_regs *regs)
|
||||
*/
|
||||
ul sys_printf(struct pt_regs *regs);
|
||||
|
||||
// 系统调用的内核入口程序
|
||||
void do_syscall_int(struct pt_regs *regs, unsigned long error_code);
|
||||
|
||||
system_call_t system_call_table[MAX_SYSTEM_CALL_NUM] =
|
||||
{
|
||||
[0] = system_call_not_exists,
|
||||
[1] = sys_printf,
|
||||
[2 ... MAX_SYSTEM_CALL_NUM - 1] = system_call_not_exists
|
||||
};
|
||||
[2 ... MAX_SYSTEM_CALL_NUM - 1] = system_call_not_exists};
|
||||
|
Loading…
x
Reference in New Issue
Block a user