mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-09 07:06:47 +00:00
使用内核线程来刷新屏幕 (#57)
* 修改了test-idr的错误 * new: 修复切换双缓冲的时候的卡顿问题 Signed-off-by: guanjinquan <1666320330@qq.com> Co-authored-by: guanjinquan <1666320330@qq.com> Co-authored-by: fslongjin <longjin@RinGoTek.cn>
This commit is contained in:
parent
1b0c901ab2
commit
efa38a7d5d
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@ -144,7 +144,8 @@
|
|||||||
"ktest_utils.h": "c",
|
"ktest_utils.h": "c",
|
||||||
"kthread.h": "c",
|
"kthread.h": "c",
|
||||||
"lockref.h": "c",
|
"lockref.h": "c",
|
||||||
"compiler_attributes.h": "c"
|
"compiler_attributes.h": "c",
|
||||||
|
"timer.h": "c"
|
||||||
},
|
},
|
||||||
"C_Cpp.errorSquiggles": "Enabled",
|
"C_Cpp.errorSquiggles": "Enabled",
|
||||||
"esbonio.sphinx.confDir": ""
|
"esbonio.sphinx.confDir": ""
|
||||||
|
@ -439,7 +439,8 @@ void pci_init()
|
|||||||
{
|
{
|
||||||
if (ptr->Status & 0x10)
|
if (ptr->Status & 0x10)
|
||||||
{
|
{
|
||||||
kinfo("[ pci device %d ] class code = %d\tsubclass=%d\tstatus=%#010lx\tcap_pointer=%#010lx\tbar5=%#010lx", i, ptr->Class_code, ptr->SubClass, ptr->Status, ((struct pci_device_structure_general_device_t *)ptr)->Capabilities_Pointer, ((struct pci_device_structure_general_device_t *)ptr)->BAR5);
|
kinfo("[ pci device %d ] class code = %d\tsubclass=%d\tstatus=%#010lx\tcap_pointer=%#010lx\tbar5=%#010lx, vendor=%#08x, device id=%#08x", i, ptr->Class_code, ptr->SubClass, ptr->Status, ((struct pci_device_structure_general_device_t *)ptr)->Capabilities_Pointer, ((struct pci_device_structure_general_device_t *)ptr)->BAR5,
|
||||||
|
ptr->Vendor_ID, ptr->Device_ID);
|
||||||
uint32_t tmp = pci_read_config(ptr->bus, ptr->device, ptr->func, ((struct pci_device_structure_general_device_t *)ptr)->Capabilities_Pointer);
|
uint32_t tmp = pci_read_config(ptr->bus, ptr->device, ptr->func, ((struct pci_device_structure_general_device_t *)ptr)->Capabilities_Pointer);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
#include "video.h"
|
#include "video.h"
|
||||||
#include <mm/mm.h>
|
|
||||||
#include <common/printk.h>
|
|
||||||
#include <driver/multiboot2/multiboot2.h>
|
|
||||||
#include <time/timer.h>
|
|
||||||
#include <common/kprint.h>
|
#include <common/kprint.h>
|
||||||
|
#include <common/kthread.h>
|
||||||
|
#include <common/printk.h>
|
||||||
|
#include <common/spinlock.h>
|
||||||
|
#include <common/time.h>
|
||||||
|
#include <driver/multiboot2/multiboot2.h>
|
||||||
|
#include <driver/uart/uart.h>
|
||||||
|
#include <exception/softirq.h>
|
||||||
#include <mm/mm.h>
|
#include <mm/mm.h>
|
||||||
#include <mm/slab.h>
|
#include <mm/slab.h>
|
||||||
#include <common/spinlock.h>
|
#include <process/process.h>
|
||||||
#include <exception/softirq.h>
|
#include <sched/sched.h>
|
||||||
#include <driver/uart/uart.h>
|
#include <time/timer.h>
|
||||||
#include <common/time.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint64_t video_refresh_expire_jiffies = 0;
|
uint64_t video_refresh_expire_jiffies = 0;
|
||||||
uint64_t video_last_refresh_pid = -1;
|
uint64_t video_last_refresh_pid = -1;
|
||||||
@ -19,10 +19,11 @@ uint64_t video_last_refresh_pid = -1;
|
|||||||
struct scm_buffer_info_t video_frame_buffer_info = {0};
|
struct scm_buffer_info_t video_frame_buffer_info = {0};
|
||||||
static struct multiboot_tag_framebuffer_info_t __fb_info;
|
static struct multiboot_tag_framebuffer_info_t __fb_info;
|
||||||
static struct scm_buffer_info_t *video_refresh_target = NULL;
|
static struct scm_buffer_info_t *video_refresh_target = NULL;
|
||||||
|
static struct process_control_block *video_daemon_pcb = NULL;
|
||||||
|
static spinlock_t daemon_refresh_lock;
|
||||||
|
|
||||||
#define REFRESH_INTERVAL 15UL // 启动刷新帧缓冲区任务的时间间隔
|
#define REFRESH_INTERVAL 15UL // 启动刷新帧缓冲区任务的时间间隔
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief VBE帧缓存区的地址重新映射
|
* @brief VBE帧缓存区的地址重新映射
|
||||||
* 将帧缓存区映射到地址SPECIAL_MEMOEY_MAPPING_VIRT_ADDR_BASE处
|
* 将帧缓存区映射到地址SPECIAL_MEMOEY_MAPPING_VIRT_ADDR_BASE处
|
||||||
@ -37,22 +38,53 @@ void init_frame_buffer()
|
|||||||
int reserved;
|
int reserved;
|
||||||
|
|
||||||
video_frame_buffer_info.vaddr = SPECIAL_MEMOEY_MAPPING_VIRT_ADDR_BASE + FRAME_BUFFER_MAPPING_OFFSET;
|
video_frame_buffer_info.vaddr = SPECIAL_MEMOEY_MAPPING_VIRT_ADDR_BASE + FRAME_BUFFER_MAPPING_OFFSET;
|
||||||
mm_map_proc_page_table(global_CR3, true, video_frame_buffer_info.vaddr, __fb_info.framebuffer_addr, video_frame_buffer_info.size, PAGE_KERNEL_PAGE | PAGE_PWT | PAGE_PCD, false, true, false);
|
mm_map_proc_page_table(global_CR3, true, video_frame_buffer_info.vaddr, __fb_info.framebuffer_addr,
|
||||||
|
video_frame_buffer_info.size, PAGE_KERNEL_PAGE | PAGE_PWT | PAGE_PCD, false, true, false);
|
||||||
|
|
||||||
flush_tlb();
|
flush_tlb();
|
||||||
kinfo("VBE frame buffer successfully Re-mapped!");
|
kinfo("VBE frame buffer successfully Re-mapped!");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 刷新帧缓冲区
|
* @brief video守护进程, 按时刷新帧缓冲区
|
||||||
*
|
* @param unused
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
int video_refresh_daemon(void *unused)
|
||||||
|
{
|
||||||
|
// 初始化锁, 这个锁只会在daemon中使用
|
||||||
|
spin_init(&daemon_refresh_lock);
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
if (clock() >= video_refresh_expire_jiffies)
|
||||||
|
{
|
||||||
|
video_refresh_expire_jiffies = cal_next_n_ms_jiffies(REFRESH_INTERVAL << 1);
|
||||||
|
|
||||||
|
if (likely(video_refresh_target != NULL))
|
||||||
|
{
|
||||||
|
spin_lock(&daemon_refresh_lock);
|
||||||
|
memcpy((void *)video_frame_buffer_info.vaddr, (void *)video_refresh_target->vaddr,
|
||||||
|
video_refresh_target->size);
|
||||||
|
spin_unlock(&daemon_refresh_lock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
video_daemon_pcb->flags &= ~PROC_RUNNING;
|
||||||
|
sched();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 唤醒video的守护进程
|
||||||
*/
|
*/
|
||||||
void video_refresh_framebuffer(void *data)
|
void video_refresh_framebuffer(void *data)
|
||||||
{
|
{
|
||||||
video_refresh_expire_jiffies = cal_next_n_ms_jiffies(REFRESH_INTERVAL << 1);
|
if (unlikely(video_daemon_pcb == NULL))
|
||||||
if (unlikely(video_refresh_target == NULL))
|
|
||||||
return;
|
return;
|
||||||
memcpy((void *)video_frame_buffer_info.vaddr, (void *)video_refresh_target->vaddr, video_refresh_target->size);
|
|
||||||
|
process_wakeup(video_daemon_pcb);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -62,17 +94,22 @@ void video_refresh_framebuffer(void *data)
|
|||||||
* true ->高级初始化:增加double buffer的支持
|
* true ->高级初始化:增加double buffer的支持
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
int video_reinitialize(bool level)
|
int video_reinitialize(bool level) // 这个函数会在main.c调用, 保证 video_init() 先被调用
|
||||||
{
|
{
|
||||||
if (level == false)
|
if (level == false)
|
||||||
init_frame_buffer();
|
init_frame_buffer();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// 计算开始时间
|
||||||
|
video_refresh_expire_jiffies = cal_next_n_ms_jiffies(10 * REFRESH_INTERVAL);
|
||||||
|
|
||||||
|
// 创建video守护进程
|
||||||
|
video_daemon_pcb = kthread_run(&video_refresh_daemon, NULL, CLONE_FS | CLONE_SIGNAL);
|
||||||
|
video_daemon_pcb->virtual_runtime = 0; // 特殊情况, 最高优先级, 以后再改
|
||||||
|
|
||||||
// 启用屏幕刷新软中断
|
// 启用屏幕刷新软中断
|
||||||
register_softirq(VIDEO_REFRESH_SIRQ, &video_refresh_framebuffer, NULL);
|
register_softirq(VIDEO_REFRESH_SIRQ, &video_refresh_framebuffer, NULL);
|
||||||
|
|
||||||
video_refresh_expire_jiffies = cal_next_n_ms_jiffies(10 * REFRESH_INTERVAL);
|
|
||||||
|
|
||||||
raise_softirq(VIDEO_REFRESH_SIRQ);
|
raise_softirq(VIDEO_REFRESH_SIRQ);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -88,12 +125,16 @@ int video_set_refresh_target(struct scm_buffer_info_t *buf)
|
|||||||
{
|
{
|
||||||
|
|
||||||
unregister_softirq(VIDEO_REFRESH_SIRQ);
|
unregister_softirq(VIDEO_REFRESH_SIRQ);
|
||||||
int counter = 100;
|
// todo: 在completion实现后,在这里等待其他刷新任务完成,再进行下一步。
|
||||||
while ((get_softirq_pending() & (1 << VIDEO_REFRESH_SIRQ)) && counter > 0)
|
|
||||||
{
|
// int counter = 100;
|
||||||
--counter;
|
|
||||||
usleep(1000);
|
// while ((get_softirq_pending() & (1 << VIDEO_REFRESH_SIRQ)) && counter > 0)
|
||||||
}
|
// {
|
||||||
|
// --counter;
|
||||||
|
// usleep(1000);
|
||||||
|
// }
|
||||||
|
// kdebug("buf = %#018lx", buf);
|
||||||
video_refresh_target = buf;
|
video_refresh_target = buf;
|
||||||
register_softirq(VIDEO_REFRESH_SIRQ, &video_refresh_framebuffer, NULL);
|
register_softirq(VIDEO_REFRESH_SIRQ, &video_refresh_framebuffer, NULL);
|
||||||
raise_softirq(VIDEO_REFRESH_SIRQ);
|
raise_softirq(VIDEO_REFRESH_SIRQ);
|
||||||
@ -134,14 +175,17 @@ int video_init()
|
|||||||
video_frame_buffer_info.height = __fb_info.framebuffer_height;
|
video_frame_buffer_info.height = __fb_info.framebuffer_height;
|
||||||
io_mfence();
|
io_mfence();
|
||||||
|
|
||||||
video_frame_buffer_info.size = video_frame_buffer_info.width * video_frame_buffer_info.height * ((video_frame_buffer_info.bit_depth + 7) / 8);
|
video_frame_buffer_info.size =
|
||||||
|
video_frame_buffer_info.width * video_frame_buffer_info.height * ((video_frame_buffer_info.bit_depth + 7) / 8);
|
||||||
// 先临时映射到该地址,稍后再重新映射
|
// 先临时映射到该地址,稍后再重新映射
|
||||||
video_frame_buffer_info.vaddr = 0xffff800003000000;
|
video_frame_buffer_info.vaddr = 0xffff800003000000;
|
||||||
mm_map_phys_addr(video_frame_buffer_info.vaddr, __fb_info.framebuffer_addr, video_frame_buffer_info.size, PAGE_KERNEL_PAGE | PAGE_PWT | PAGE_PCD, false);
|
mm_map_phys_addr(video_frame_buffer_info.vaddr, __fb_info.framebuffer_addr, video_frame_buffer_info.size,
|
||||||
|
PAGE_KERNEL_PAGE | PAGE_PWT | PAGE_PCD, false);
|
||||||
|
|
||||||
io_mfence();
|
io_mfence();
|
||||||
char init_text2[] = "Video driver initialized.";
|
char init_text2[] = "Video driver initialized.";
|
||||||
for (int i = 0; i < sizeof(init_text2) - 1; ++i)
|
for (int i = 0; i < sizeof(init_text2) - 1; ++i)
|
||||||
uart_send(COM1, init_text2[i]);
|
uart_send(COM1, init_text2[i]);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
@ -33,7 +33,7 @@ static long ktest_idr_case0(uint64_t arg0, uint64_t arg1)
|
|||||||
idr_init(&k_idr);
|
idr_init(&k_idr);
|
||||||
assert(k_idr.id_free_cnt == 0);
|
assert(k_idr.id_free_cnt == 0);
|
||||||
|
|
||||||
assert(idr_pre_get(&k_idr, 0) == 1);
|
assert(idr_pre_get(&k_idr, 0) == 0);
|
||||||
assert(k_idr.id_free_cnt == IDR_FREE_MAX);
|
assert(k_idr.id_free_cnt == IDR_FREE_MAX);
|
||||||
|
|
||||||
for (int i = 1; i < 64; i++)
|
for (int i = 1; i < 64; i++)
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
#include "screen_manager.h"
|
#include "screen_manager.h"
|
||||||
#include <common/string.h>
|
|
||||||
#include <driver/multiboot2/multiboot2.h>
|
|
||||||
#include <common/kprint.h>
|
#include <common/kprint.h>
|
||||||
#include <common/spinlock.h>
|
#include <common/spinlock.h>
|
||||||
#include <mm/mm.h>
|
#include <common/string.h>
|
||||||
#include <mm/slab.h>
|
#include <driver/multiboot2/multiboot2.h>
|
||||||
#include <driver/uart/uart.h>
|
#include <driver/uart/uart.h>
|
||||||
#include <driver/video/video.h>
|
#include <driver/video/video.h>
|
||||||
|
#include <mm/mm.h>
|
||||||
|
#include <mm/slab.h>
|
||||||
|
|
||||||
extern struct scm_buffer_info_t video_frame_buffer_info;
|
extern struct scm_buffer_info_t video_frame_buffer_info;
|
||||||
static struct List scm_framework_list;
|
static struct List scm_framework_list;
|
||||||
@ -234,35 +234,43 @@ int scm_enable_alloc()
|
|||||||
*/
|
*/
|
||||||
int scm_enable_double_buffer()
|
int scm_enable_double_buffer()
|
||||||
{
|
{
|
||||||
if (__scm_double_buffer_enabled == true)
|
if (__scm_double_buffer_enabled == true) // 已经开启了双缓冲区了, 直接退出
|
||||||
return 0;
|
return 0;
|
||||||
__scm_double_buffer_enabled = true;
|
__scm_double_buffer_enabled = true;
|
||||||
if (list_empty(&scm_framework_list))
|
if (list_empty(&scm_framework_list)) // scm 框架链表为空
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// 逐个检查已经注册了的ui框架,将其缓冲区更改为双缓冲
|
// 逐个检查已经注册了的ui框架,将其缓冲区更改为双缓冲
|
||||||
struct scm_ui_framework_t *ptr = container_of(list_next(&scm_framework_list), struct scm_ui_framework_t, list);
|
struct scm_ui_framework_t *ptr = container_of(list_next(&scm_framework_list), struct scm_ui_framework_t, list);
|
||||||
|
// 这里的ptr不需要特判空指针吗 问题1
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if (ptr->buf == &video_frame_buffer_info)
|
if (ptr->buf == &video_frame_buffer_info)
|
||||||
{
|
{
|
||||||
uart_send_str(COM1, "##init double buffer##");
|
uart_send_str(COM1, "##init double buffer##\n");
|
||||||
struct scm_buffer_info_t *buf = __create_buffer(SCM_BF_DB | SCM_BF_PIXEL);
|
struct scm_buffer_info_t *buf = __create_buffer(SCM_BF_DB | SCM_BF_PIXEL);
|
||||||
if ((uint64_t)(buf) == (uint64_t)-ENOMEM)
|
if ((uint64_t)(buf) == (uint64_t)-ENOMEM)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
uart_send_str(COM1, "##to change double buffer##");
|
uart_send_str(COM1, "##to change double buffer##\n");
|
||||||
if (ptr->ui_ops->change(buf) != 0)
|
|
||||||
|
if (ptr->ui_ops->change(buf) != 0) // 这里的change回调函数不会是空指针吗 问题2
|
||||||
{
|
{
|
||||||
|
|
||||||
__destroy_buffer(buf);
|
__destroy_buffer(buf);
|
||||||
kfree(buf);
|
kfree(buf);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
} while (list_next(&ptr->list) != &scm_framework_list);
|
|
||||||
|
} while (list_next(&ptr->list) != &scm_framework_list); // 枚举链表的每一个ui框架
|
||||||
|
|
||||||
|
|
||||||
// 设置定时刷新的对象
|
// 设置定时刷新的对象
|
||||||
video_set_refresh_target(__current_framework->buf);
|
video_set_refresh_target(__current_framework->buf);
|
||||||
// 通知显示驱动,启动双缓冲
|
// 通知显示驱动,启动双缓冲
|
||||||
video_reinitialize(true);
|
video_reinitialize(true);
|
||||||
uart_send_str(COM1, "##initialized double buffer##");
|
uart_send_str(COM1, "##initialized double buffer##\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
#include "textui.h"
|
#include "textui.h"
|
||||||
|
|
||||||
#include "screen_manager.h"
|
|
||||||
#include "driver/uart/uart.h"
|
#include "driver/uart/uart.h"
|
||||||
#include <common/string.h>
|
#include "screen_manager.h"
|
||||||
#include <common/printk.h>
|
|
||||||
#include <common/atomic.h>
|
#include <common/atomic.h>
|
||||||
#include <common/errno.h>
|
#include <common/errno.h>
|
||||||
|
#include <common/printk.h>
|
||||||
|
#include <common/string.h>
|
||||||
|
|
||||||
struct scm_ui_framework_t textui_framework;
|
struct scm_ui_framework_t textui_framework;
|
||||||
static spinlock_t __window_id_lock = {1};
|
static spinlock_t __window_id_lock = {1};
|
||||||
@ -19,6 +19,7 @@ static struct textui_vline_chromatic_t __initial_vlines[INITIAL_VLINES] = {0};
|
|||||||
static struct textui_window_t __initial_window = {0}; // 初始窗口
|
static struct textui_window_t __initial_window = {0}; // 初始窗口
|
||||||
static struct textui_private_info_t __private_info = {0};
|
static struct textui_private_info_t __private_info = {0};
|
||||||
static struct List __windows_list;
|
static struct List __windows_list;
|
||||||
|
static spinlock_t change_lock;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 初始化window对象
|
* @brief 初始化window对象
|
||||||
@ -29,7 +30,8 @@ static struct List __windows_list;
|
|||||||
* @param vlines_ptr 虚拟行数组指针
|
* @param vlines_ptr 虚拟行数组指针
|
||||||
* @param cperline 每行最大的字符数
|
* @param cperline 每行最大的字符数
|
||||||
*/
|
*/
|
||||||
static int __textui_init_window(struct textui_window_t *window, uint8_t flags, uint16_t vlines_num, void *vlines_ptr, uint16_t cperline)
|
static int __textui_init_window(struct textui_window_t *window, uint8_t flags, uint16_t vlines_num, void *vlines_ptr,
|
||||||
|
uint16_t cperline)
|
||||||
{
|
{
|
||||||
memset((window), 0, sizeof(struct textui_window_t));
|
memset((window), 0, sizeof(struct textui_window_t));
|
||||||
list_init(&(window)->list);
|
list_init(&(window)->list);
|
||||||
@ -56,12 +58,12 @@ static int __textui_init_window(struct textui_window_t *window, uint8_t flags, u
|
|||||||
* @param vline 虚拟行对象指针
|
* @param vline 虚拟行对象指针
|
||||||
* @param chars_ptr 字符对象数组指针
|
* @param chars_ptr 字符对象数组指针
|
||||||
*/
|
*/
|
||||||
#define __textui_init_vline(vline, chars_ptr) \
|
#define __textui_init_vline(vline, chars_ptr) \
|
||||||
do \
|
do \
|
||||||
{ \
|
{ \
|
||||||
memset(vline, 0, sizeof(struct textui_vline_chromatic_t)); \
|
memset(vline, 0, sizeof(struct textui_vline_chromatic_t)); \
|
||||||
(vline)->index = 0; \
|
(vline)->index = 0; \
|
||||||
(vline)->chars = chars_ptr; \
|
(vline)->chars = chars_ptr; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
int textui_install_handler(struct scm_buffer_info_t *buf)
|
int textui_install_handler(struct scm_buffer_info_t *buf)
|
||||||
@ -78,7 +80,7 @@ int textui_uninstall_handler(void *args)
|
|||||||
|
|
||||||
int textui_enable_handler(void *args)
|
int textui_enable_handler(void *args)
|
||||||
{
|
{
|
||||||
uart_send_str(COM1, "textui_enable_handler");
|
uart_send_str(COM1, "textui_enable_handler\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,16 +93,16 @@ int textui_change_handler(struct scm_buffer_info_t *buf)
|
|||||||
{
|
{
|
||||||
memcpy((void *)buf->vaddr, (void *)(textui_framework.buf->vaddr), textui_framework.buf->size);
|
memcpy((void *)buf->vaddr, (void *)(textui_framework.buf->vaddr), textui_framework.buf->size);
|
||||||
textui_framework.buf = buf;
|
textui_framework.buf = buf;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct scm_ui_framework_operations_t textui_ops =
|
struct scm_ui_framework_operations_t textui_ops = {
|
||||||
{
|
.install = &textui_install_handler,
|
||||||
.install = &textui_install_handler,
|
.uninstall = &textui_uninstall_handler,
|
||||||
.uninstall = &textui_uninstall_handler,
|
.change = &textui_change_handler,
|
||||||
.change = &textui_change_handler,
|
.enable = &textui_enable_handler,
|
||||||
.enable = &textui_enable_handler,
|
.disable = &textui_disable_handler,
|
||||||
.disable = &textui_disable_handler,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -166,7 +168,8 @@ static int __textui_new_line(struct textui_window_t *window, uint16_t vline_id)
|
|||||||
* @param character
|
* @param character
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
static int __textui_putchar_window(struct textui_window_t *window, uint16_t character, uint32_t FRcolor, uint32_t BKcolor)
|
static int __textui_putchar_window(struct textui_window_t *window, uint16_t character, uint32_t FRcolor,
|
||||||
|
uint32_t BKcolor)
|
||||||
{
|
{
|
||||||
if (textui_is_chromatic(window->flags)) // 启用彩色字符
|
if (textui_is_chromatic(window->flags)) // 启用彩色字符
|
||||||
{
|
{
|
||||||
@ -246,7 +249,8 @@ int textui_putchar_window(struct textui_window_t *window, uint16_t character, ui
|
|||||||
if (window->vlines.chromatic[window->vline_operating].index <= 0)
|
if (window->vlines.chromatic[window->vline_operating].index <= 0)
|
||||||
{
|
{
|
||||||
window->vlines.chromatic[window->vline_operating].index = 0;
|
window->vlines.chromatic[window->vline_operating].index = 0;
|
||||||
memset(window->vlines.chromatic[window->vline_operating].chars, 0, sizeof(struct textui_char_chromatic_t) * window->chars_per_line);
|
memset(window->vlines.chromatic[window->vline_operating].chars, 0,
|
||||||
|
sizeof(struct textui_char_chromatic_t) * window->chars_per_line);
|
||||||
--(window->vline_operating);
|
--(window->vline_operating);
|
||||||
if (unlikely(window->vline_operating < 0))
|
if (unlikely(window->vline_operating < 0))
|
||||||
window->vline_operating = window->vlines_num - 1;
|
window->vline_operating = window->vlines_num - 1;
|
||||||
@ -295,6 +299,8 @@ int textui_putchar(uint16_t character, uint32_t FRcolor, uint32_t BKcolor)
|
|||||||
*/
|
*/
|
||||||
int textui_init()
|
int textui_init()
|
||||||
{
|
{
|
||||||
|
spin_init(&change_lock);
|
||||||
|
|
||||||
spin_init(&__window_id_lock);
|
spin_init(&__window_id_lock);
|
||||||
__window_max_id = 0;
|
__window_max_id = 0;
|
||||||
list_init(&__windows_list);
|
list_init(&__windows_list);
|
||||||
|
@ -165,7 +165,7 @@ void system_initialize()
|
|||||||
|
|
||||||
process_init();
|
process_init();
|
||||||
// 启用double buffer
|
// 启用double buffer
|
||||||
scm_enable_double_buffer();
|
// scm_enable_double_buffer(); // 因为时序问题, 该函数调用被移到 initial_kernel_thread
|
||||||
io_mfence();
|
io_mfence();
|
||||||
|
|
||||||
// fat32_init();
|
// fat32_init();
|
||||||
|
@ -1,29 +1,29 @@
|
|||||||
#include "process.h"
|
#include "process.h"
|
||||||
|
|
||||||
#include <common/printk.h>
|
|
||||||
#include <common/kprint.h>
|
|
||||||
#include <common/stdio.h>
|
|
||||||
#include <common/string.h>
|
|
||||||
#include <common/compiler.h>
|
#include <common/compiler.h>
|
||||||
#include <common/elf.h>
|
#include <common/elf.h>
|
||||||
|
#include <common/kprint.h>
|
||||||
#include <common/kthread.h>
|
#include <common/kthread.h>
|
||||||
#include <common/time.h>
|
#include <common/printk.h>
|
||||||
|
#include <common/spinlock.h>
|
||||||
|
#include <common/stdio.h>
|
||||||
|
#include <common/string.h>
|
||||||
#include <common/sys/wait.h>
|
#include <common/sys/wait.h>
|
||||||
#include <driver/video/video.h>
|
#include <common/time.h>
|
||||||
|
#include <common/unistd.h>
|
||||||
|
#include <debug/bug.h>
|
||||||
|
#include <debug/traceback/traceback.h>
|
||||||
|
#include <driver/disk/ahci/ahci.h>
|
||||||
#include <driver/usb/usb.h>
|
#include <driver/usb/usb.h>
|
||||||
|
#include <driver/video/video.h>
|
||||||
#include <exception/gate.h>
|
#include <exception/gate.h>
|
||||||
#include <filesystem/fat32/fat32.h>
|
|
||||||
#include <filesystem/devfs/devfs.h>
|
#include <filesystem/devfs/devfs.h>
|
||||||
|
#include <filesystem/fat32/fat32.h>
|
||||||
#include <filesystem/rootfs/rootfs.h>
|
#include <filesystem/rootfs/rootfs.h>
|
||||||
#include <mm/slab.h>
|
#include <mm/slab.h>
|
||||||
#include <common/spinlock.h>
|
#include <sched/sched.h>
|
||||||
#include <syscall/syscall.h>
|
#include <syscall/syscall.h>
|
||||||
#include <syscall/syscall_num.h>
|
#include <syscall/syscall_num.h>
|
||||||
#include <sched/sched.h>
|
|
||||||
#include <common/unistd.h>
|
|
||||||
#include <debug/traceback/traceback.h>
|
|
||||||
#include <debug/bug.h>
|
|
||||||
#include <driver/disk/ahci/ahci.h>
|
|
||||||
|
|
||||||
#include <ktest/ktest.h>
|
#include <ktest/ktest.h>
|
||||||
|
|
||||||
@ -372,7 +372,7 @@ ul do_execve(struct pt_regs *regs, char *path, char *argv[], char *envp[])
|
|||||||
// 独立的地址空间才能使新程序正常运行
|
// 独立的地址空间才能使新程序正常运行
|
||||||
if (current_pcb->flags & PF_VFORK)
|
if (current_pcb->flags & PF_VFORK)
|
||||||
{
|
{
|
||||||
kdebug("proc:%d creating new mem space", current_pcb->pid);
|
// kdebug("proc:%d creating new mem space", current_pcb->pid);
|
||||||
// 分配新的内存空间分布结构体
|
// 分配新的内存空间分布结构体
|
||||||
struct mm_struct *new_mms = (struct mm_struct *)kmalloc(sizeof(struct mm_struct), 0);
|
struct mm_struct *new_mms = (struct mm_struct *)kmalloc(sizeof(struct mm_struct), 0);
|
||||||
memset(new_mms, 0, sizeof(struct mm_struct));
|
memset(new_mms, 0, sizeof(struct mm_struct));
|
||||||
@ -479,7 +479,9 @@ exec_failed:;
|
|||||||
#pragma GCC optimize("O0")
|
#pragma GCC optimize("O0")
|
||||||
ul initial_kernel_thread(ul arg)
|
ul initial_kernel_thread(ul arg)
|
||||||
{
|
{
|
||||||
// kinfo("initial proc running...\targ:%#018lx", arg);
|
kinfo("initial proc running...\targ:%#018lx", arg);
|
||||||
|
|
||||||
|
scm_enable_double_buffer();
|
||||||
|
|
||||||
ahci_init();
|
ahci_init();
|
||||||
fat32_init();
|
fat32_init();
|
||||||
@ -582,7 +584,7 @@ ul process_do_exit(ul code)
|
|||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
|
|
||||||
pid_t kernel_thread(int (*fn)(void*), void* arg, unsigned long flags)
|
pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
|
||||||
{
|
{
|
||||||
struct pt_regs regs;
|
struct pt_regs regs;
|
||||||
barrier();
|
barrier();
|
||||||
@ -794,13 +796,16 @@ struct process_control_block *process_get_pcb(long pid)
|
|||||||
*/
|
*/
|
||||||
int process_wakeup(struct process_control_block *pcb)
|
int process_wakeup(struct process_control_block *pcb)
|
||||||
{
|
{
|
||||||
|
// kdebug("pcb pid = %#018lx", pcb->pid);
|
||||||
|
|
||||||
BUG_ON(pcb == NULL);
|
BUG_ON(pcb == NULL);
|
||||||
if (pcb == current_pcb || pcb == NULL)
|
if (pcb == current_pcb || pcb == NULL)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
// 如果pcb正在调度队列中,则不重复加入调度队列
|
// 如果pcb正在调度队列中,则不重复加入调度队列
|
||||||
if (pcb->state == PROC_RUNNING)
|
if (pcb->state & PROC_RUNNING)
|
||||||
return 0;
|
return 0;
|
||||||
pcb->state = PROC_RUNNING;
|
|
||||||
|
pcb->state |= PROC_RUNNING;
|
||||||
sched_enqueue(pcb);
|
sched_enqueue(pcb);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -812,7 +817,7 @@ int process_wakeup(struct process_control_block *pcb)
|
|||||||
*/
|
*/
|
||||||
int process_wakeup_immediately(struct process_control_block *pcb)
|
int process_wakeup_immediately(struct process_control_block *pcb)
|
||||||
{
|
{
|
||||||
if (pcb->state == PROC_RUNNING)
|
if (pcb->state & PROC_RUNNING)
|
||||||
return 0;
|
return 0;
|
||||||
int retval = process_wakeup(pcb);
|
int retval = process_wakeup(pcb);
|
||||||
if (retval != 0)
|
if (retval != 0)
|
||||||
|
@ -69,10 +69,10 @@ void sched_cfs()
|
|||||||
current_pcb->flags &= ~PF_NEED_SCHED;
|
current_pcb->flags &= ~PF_NEED_SCHED;
|
||||||
struct process_control_block *proc = sched_cfs_dequeue();
|
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);
|
// 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->virtual_runtime >= proc->virtual_runtime || !(current_pcb->state & PROC_RUNNING)) // 当前进程运行时间大于了下一进程的运行时间,进行切换
|
||||||
{
|
{
|
||||||
|
|
||||||
if (current_pcb->state == PROC_RUNNING) // 本次切换由于时间片到期引发,则再次加入就绪队列,否则交由其它功能模块进行管理
|
if (current_pcb->state & PROC_RUNNING) // 本次切换由于时间片到期引发,则再次加入就绪队列,否则交由其它功能模块进行管理
|
||||||
sched_cfs_enqueue(current_pcb);
|
sched_cfs_enqueue(current_pcb);
|
||||||
// kdebug("proc->pid=%d, count=%d", proc->pid, sched_cfs_ready_queue[proc_current_cpu_id].count);
|
// 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)
|
if (sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies <= 0)
|
||||||
|
@ -7,9 +7,9 @@
|
|||||||
uint64_t volatile timer_jiffies = 0; // 系统时钟计数
|
uint64_t volatile timer_jiffies = 0; // 系统时钟计数
|
||||||
|
|
||||||
// 计算接下来n毫秒对应的系统时间片
|
// 计算接下来n毫秒对应的系统时间片
|
||||||
#define cal_next_n_ms_jiffies(expire_ms) (timer_jiffies + 1000*expire_ms)
|
#define cal_next_n_ms_jiffies(expire_ms) (timer_jiffies + 1000 * (expire_ms))
|
||||||
// 计算接下来n微秒对应的系统时间片
|
// 计算接下来n微秒对应的系统时间片
|
||||||
#define cal_next_n_us_jiffies(expire_us) (timer_jiffies + expire_us)
|
#define cal_next_n_us_jiffies(expire_us) (timer_jiffies + (expire_us))
|
||||||
|
|
||||||
void timer_init();
|
void timer_init();
|
||||||
|
|
||||||
@ -62,5 +62,4 @@ void timer_func_add(struct timer_func_list_t *timer_func);
|
|||||||
*/
|
*/
|
||||||
void timer_func_del(struct timer_func_list_t *timer_func);
|
void timer_func_del(struct timer_func_list_t *timer_func);
|
||||||
|
|
||||||
|
|
||||||
uint64_t clock();
|
uint64_t clock();
|
||||||
|
1
run.sh
1
run.sh
@ -174,6 +174,7 @@ if [ $flag_can_run -eq 1 ]; then
|
|||||||
-drive id=disk,file=bin/disk.img,if=none \
|
-drive id=disk,file=bin/disk.img,if=none \
|
||||||
-device ahci,id=ahci \
|
-device ahci,id=ahci \
|
||||||
-device ide-hd,drive=disk,bus=ahci.0 \
|
-device ide-hd,drive=disk,bus=ahci.0 \
|
||||||
|
-net nic,model=virtio \
|
||||||
-usb \
|
-usb \
|
||||||
-device qemu-xhci,id=xhci,p2=8,p3=4 \
|
-device qemu-xhci,id=xhci,p2=8,p3=4 \
|
||||||
-machine accel=${qemu_accel}
|
-machine accel=${qemu_accel}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user