new: 初步完成了textui的基本显示功能

This commit is contained in:
fslongjin 2022-08-04 21:40:26 +08:00
parent 36d55511ba
commit 17d5fea2cf
9 changed files with 615 additions and 104 deletions

View File

@ -117,7 +117,10 @@
"sched.h": "c",
"preempt.h": "c",
"softirq.h": "c",
"screen_manager.h": "c"
"screen_manager.h": "c",
"textui.h": "c",
"atomic.h": "c",
"uart.h": "c"
},
"C_Cpp.errorSquiggles": "Enabled",
"esbonio.sphinx.confDir": ""

View File

@ -13,10 +13,11 @@
#include <driver/video/video.h>
#include "math.h"
#include <common/string.h>
#include <lib/libUI/textui.h>
struct printk_screen_info pos;
static spinlock_t printk_lock;
static spinlock_t printk_lock={1};
static bool sw_show_scroll_animation = false; // 显示换行动画的开关
/**
@ -662,49 +663,6 @@ static char *write_float_point_num(char *str, double num, int field_width, int p
return str;
}
static void putchar(uint *fb, int Xsize, int x, int y, unsigned int FRcolor, unsigned int BKcolor, unsigned char font)
{
/**
* @brief
*
* @param fb 线
* @param Xsize
* @param x
* @param y
* @param FRcolor
* @param BKcolor
* @param font bitmap
*/
//#if DEBUG
uart_send(COM1, font);
//#endif
unsigned char *font_ptr = font_ascii[font];
unsigned int *addr;
int testbit; // 用来测试某位是背景还是字体本身
for (int i = 0; i < pos.char_size_y; ++i)
{
// 计算出帧缓冲区的地址
addr = fb + Xsize * (y + i) + x;
testbit = (1 << (pos.char_size_x + 1));
for (int j = 0; j < pos.char_size_x; ++j)
{
//从左往右逐个测试相应位
testbit >>= 1;
if (*font_ptr & testbit)
*addr = FRcolor; // 字,显示前景色
else
*addr = BKcolor; // 背景色
++addr;
}
++font_ptr;
}
}
/**
* @brief
*
@ -715,9 +673,6 @@ static void putchar(uint *fb, int Xsize, int x, int y, unsigned int FRcolor, uns
int printk_color(unsigned int FRcolor, unsigned int BKcolor, const char *fmt, ...)
{
uint64_t rflags = 0; // 加锁后rflags存储到这里
spin_lock_irqsave(&printk_lock, rflags);
va_list args;
va_start(args, fmt);
char buf[4096]; // vsprintf()的缓冲区
@ -733,47 +688,43 @@ int printk_color(unsigned int FRcolor, unsigned int BKcolor, const char *fmt, ..
//输出换行
if (current == '\n')
{
pos.x = 0;
++pos.y;
auto_newline();
}
else if (current == '\t') // 输出制表符
{
int space_to_print = 8 - pos.x % 8;
while (space_to_print--)
{
putchar(pos.FB_address, pos.width, pos.x * pos.char_size_x, pos.y * pos.char_size_y, FRcolor, BKcolor, ' ');
++pos.x;
textui_putchar(current);
}
// else if (current == '\t') // 输出制表符
// {
// int space_to_print = 8 - pos.x % 8;
auto_newline();
}
}
else if (current == '\b') // 退格
{
--pos.x;
if (pos.x < 0)
{
--pos.y;
if (pos.y <= 0)
pos.x = pos.y = 0;
else
pos.x = pos.max_x;
}
// while (space_to_print--)
// {
// textui_putchar(' ');
// ++pos.x;
// }
// }
// else if (current == '\b') // 退格
// {
// --pos.x;
// if (pos.x < 0)
// {
// --pos.y;
// if (pos.y <= 0)
// pos.x = pos.y = 0;
// else
// pos.x = pos.max_x;
// }
putchar(pos.FB_address, pos.width, pos.x * pos.char_size_x, pos.y * pos.char_size_y, FRcolor, BKcolor, ' ');
// textui_putchar(' ');
auto_newline();
}
// auto_newline();
// }
else
{
putchar(pos.FB_address, pos.width, pos.x * pos.char_size_x, pos.y * pos.char_size_y, FRcolor, BKcolor, current);
++pos.x;
auto_newline();
if (current != '\0')
textui_putchar(current);
}
}
spin_unlock_irqrestore(&printk_lock, rflags);
// spin_unlock_irqrestore(&printk_lock, rflags);
return i;
}

View File

@ -1,5 +1,5 @@
all: screen_manager.o textui.o
all: screen_manager.o textui.o textui-render.o
CFLAGS += -I .
@ -8,3 +8,6 @@ screen_manager.o: screen_manager.c
textui.o: textui.c
gcc $(CFLAGS) -c textui.c -o textui.o
textui-render.o: textui-render.c
gcc $(CFLAGS) -c textui-render.c -o textui-render.o

View File

@ -8,8 +8,6 @@
#include <driver/uart/uart.h>
#include <driver/video/video.h>
extern struct scm_buffer_info_t video_frame_buffer_info;
static struct List scm_framework_list;
static spinlock_t scm_register_lock; // 框架注册锁
@ -32,7 +30,7 @@ static struct scm_buffer_info_t *__create_buffer(uint64_t type)
struct scm_buffer_info_t *buf = (struct scm_buffer_info_t *)kmalloc(sizeof(struct scm_buffer_info_t), 0);
if (buf == NULL)
return (void*)-ENOMEM;
return (void *)-ENOMEM;
memset(buf, 0, sizeof(struct scm_buffer_info_t));
buf->bit_depth = video_frame_buffer_info.bit_depth;
buf->flags = SCM_BF_DB;
@ -52,7 +50,7 @@ static struct scm_buffer_info_t *__create_buffer(uint64_t type)
return buf;
failed:;
kfree(buf);
return (void*)-ENOMEM;
return (void *)-ENOMEM;
}
/**
@ -106,7 +104,7 @@ static int __check_ui_param(const char *name, const uint8_t type, const struct s
{
if (name == NULL)
return -EINVAL;
if (!(type == SCM_FRAMWORK_TYPE_GUI || type == SCM_FRAMWORK_TYPE_TEXT))
if ((type == SCM_FRAMWORK_TYPE_GUI || type == SCM_FRAMWORK_TYPE_TEXT) == 0)
return -EINVAL;
if (ops == NULL)
return -EINVAL;

View File

@ -9,8 +9,8 @@
#define SCM_BF_PIXEL (1 << 3) // 使用图像模式
// ui框架类型
#define SCM_FRAMWORK_TYPE_TEXT 0
#define SCM_FRAMWORK_TYPE_GUI 1
#define SCM_FRAMWORK_TYPE_TEXT (uint8_t)0
#define SCM_FRAMWORK_TYPE_GUI (uint8_t)1
/**
* @brief
@ -47,7 +47,7 @@ struct scm_ui_framework_t
uint8_t type;
struct scm_ui_framework_operations_t *ui_ops;
struct scm_buffer_info_t *buf;
} __attribute__((aligned(sizeof(uint64_t))));
};
/**
* @brief

View File

@ -0,0 +1,155 @@
#include "textui.h"
#include <driver/uart/uart.h>
#define WHITE 0x00ffffff //白
#define BLACK 0x00000000 //黑
#define RED 0x00ff0000 //红
#define ORANGE 0x00ff8000 //橙
#define YELLOW 0x00ffff00 //黄
#define GREEN 0x0000ff00 //绿
#define BLUE 0x000000ff //蓝
#define INDIGO 0x0000ffff //靛
#define PURPLE 0x008000ff //紫
// 根据rgb计算出最终的颜色值
#define calculate_color(r, g, b) ((((r & 0xff) << 16) | ((g & 0xff) << 8) | (b & 0xff)) & 0x00ffffff)
extern struct scm_ui_framework_t textui_framework;
static void __textui_render_chromatic(uint16_t actual_line, uint16_t index, struct textui_char_chromatic_t *character);
/**
* @brief
*
* @param window
* @param vline_id
* @return int
*/
int textui_refresh_vline(struct textui_window_t *window, uint16_t vline_id)
{
if (textui_is_chromatic(window->flags))
return textui_refresh_characters(window, vline_id, 0, window->chars_per_line);
else
return textui_refresh_characters(window, vline_id, 0, window->chars_per_line);
}
int textui_refresh_vlines(struct textui_window_t *window, uint16_t start, uint16_t count)
{
char bufff[16] = {0};
// uart_send_str(COM1, " BEGIN ");
for (int i = start; i < window->vlines_num && count > 0; ++i, --count)
{
// sprintk(bufff, "[ 1fresh: %d ] ", i);
// uart_send_str(COM1, bufff);
textui_refresh_vline(window, i);
}
start = 0;
while (count>0)
{
// sprintk(bufff, "[ 2fresh: %d ] ", start);
// uart_send_str(COM1, bufff);
// sprintk(bufff, " index=%d ", (window->vlines.chromatic)[start].index);
// uart_send_str(COM1, bufff);
textui_refresh_vline(window, start);
++start;
--count;
}
// uart_send_str(COM1, " END ");
return 0;
}
/**
* @brief n个字符对象
*
* @param window
* @param vline_id
* @param start
* @param count
* @return int
*/
int textui_refresh_characters(struct textui_window_t *window, uint16_t vline_id, uint16_t start, uint16_t count)
{
if (window->id != __textui_get_current_window_id())
return 0;
// 判断虚拟行参数是否合法
if (unlikely(vline_id >= window->vlines_num && (start + count) > window->chars_per_line))
return -EINVAL;
// 计算虚拟行对应的真实行
int actual_line_id = (int)vline_id - window->top_vline;
if (actual_line_id < 0)
actual_line_id += __textui_get_actual_lines();
// 判断真实行id是否合理
if (unlikely(actual_line_id < 0 || actual_line_id >= __textui_get_actual_lines()))
return 0;
// 若是彩色像素模式
if (textui_is_chromatic(window->flags))
{
struct textui_vline_chromatic_t *vline = &(window->vlines.chromatic)[vline_id];
for (int i = 0; i < count; ++i)
{
__textui_render_chromatic(actual_line_id, start + i, &vline->chars[start + i]);
}
}
return 0;
}
/**
* @brief
*
* @param actual_line
* @param index
* @param character
*/
static void __textui_render_chromatic(uint16_t actual_line, uint16_t index, struct textui_char_chromatic_t *character)
{
/**
* @brief
*
* @param x
* @param y
* @param FRcolor
* @param BKcolor
* @param font bitmap
*/
// #if DEBUG
// uart_send(COM1, font);
// #endif
unsigned char *font_ptr = font_ascii[(uint8_t)character->c];
unsigned int *addr;
uint32_t *fb = (uint32_t *)textui_framework.buf->vaddr;
// uint32_t FRcolor = YELLOW;
uint32_t FRcolor = calculate_color(character->Fr, character->Fg, character->Fb);
// uint32_t BKcolor = BLACK;
uint32_t BKcolor = calculate_color(character->Br, character->Bg, character->Bb);
uint32_t x = index * TEXTUI_CHAR_WIDTH;
uint32_t y = actual_line * TEXTUI_CHAR_HEIGHT;
int testbit; // 用来测试某位是背景还是字体本身
for (int i = 0; i < TEXTUI_CHAR_HEIGHT; ++i)
{
// 计算出帧缓冲区的地址
addr = (uint32_t *)(fb + textui_framework.buf->width * (y + i) + x);
testbit = (1 << (TEXTUI_CHAR_WIDTH + 1));
for (int j = 0; j < TEXTUI_CHAR_WIDTH; ++j)
{
// 从左往右逐个测试相应位
testbit >>= 1;
if (*font_ptr & testbit)
*addr = FRcolor; // 字,显示前景色
else
*addr = BKcolor; // 背景色
++addr;
}
++font_ptr;
}
}

View File

@ -4,31 +4,93 @@
#include "driver/uart/uart.h"
#include <common/string.h>
#include <common/printk.h>
#include <common/atomic.h>
struct scm_ui_framework_t textui_framework;
static spinlock_t __window_id_lock = {1};
static uint32_t __window_max_id = 0;
// 暂时初始化16080个初始字符对象以及67个虚拟行对象
#define INITIAL_CHARS 16080
#define INITIAL_VLINES (int)(1080 / 16)
static struct textui_char_chromatic_t __initial_chars[INITIAL_CHARS] = {0};
static struct textui_vline_chromatic_t __initial_vlines[INITIAL_VLINES] = {0};
static struct textui_window_t __initial_window = {0}; // 初始窗口
static struct textui_private_info_t __private_info = {0};
static struct List __windows_list;
/**
* @brief window对象
*
* @param window
* @param flags
* @param vlines_num
* @param vlines_ptr
* @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)
{
memset((window), 0, sizeof(struct textui_window_t));
list_init(&(window)->list);
window->lock.lock = 1;
spin_lock(&__window_id_lock);
window->id = __window_max_id++;
spin_unlock(&__window_id_lock);
window->flags = flags;
window->vlines_num = vlines_num;
window->vlines_used = 1;
window->top_vline = 0;
window->vline_operating = 0;
window->chars_per_line = cperline;
if (textui_is_chromatic(flags))
window->vlines.chromatic = vlines_ptr;
else
window->vlines.normal = vlines_ptr;
list_add(&__windows_list, &(window)->list);
}
/**
* @brief
*
* @param vline
* @param chars_ptr
*/
#define __textui_init_vline(vline, chars_ptr) \
do \
{ \
memset(vline, 0, sizeof(struct textui_vline_chromatic_t)); \
(vline)->index = 0; \
(vline)->chars = chars_ptr; \
} while (0)
int textui_install_handler(struct scm_buffer_info_t *buf)
{
return printk_init(buf);
// return printk_init(buf);
uart_send_str(COM1, "textui_install_handler");
return 0;
}
int textui_uninstall_handler(void *args)
{
return 0;
}
int textui_enable_handler(void *args)
{
uart_send_str(COM1, "textui_enable_handler");
return 0;
}
int textui_disable_handler(void *args)
{
return 0;
}
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;
set_pos_VBE_FB_addr((uint*)buf->vaddr);
set_pos_VBE_FB_addr((uint *)buf->vaddr);
return 0;
}
@ -41,6 +103,172 @@ struct scm_ui_framework_operations_t textui_ops =
.disable = &textui_disable_handler,
};
/**
* @brief textui的帧缓冲区能容纳的内容的行数
*
* @return uint16_t
*/
uint16_t __textui_get_actual_lines()
{
return __private_info.actual_line;
}
/**
* @brief id
*
* @return uint16_t
*/
uint32_t __textui_get_current_window_id()
{
return __private_info.current_window->id;
}
/**
* @brief
*
* @param window
* @param vline_id
* @return int
*/
static int __textui_new_line(struct textui_window_t *window, uint16_t vline_id)
{
// todo: 支持在两个虚拟行之间插入一个新行
++window->vline_operating;
if (unlikely(window->vline_operating == window->vlines_num))
window->vline_operating = 0;
struct textui_vline_chromatic_t *vline = &window->vlines.chromatic[window->vline_operating];
memset(vline->chars, 0, sizeof(struct textui_char_chromatic_t) * window->chars_per_line);
vline->index = 0;
if (likely(window->vlines_used == window->vlines_num)) // 需要滚动屏幕
{
// uart_send_str(COM1, " scroll, top vline= ");
++window->top_vline;
// uart_send(COM1, '0' + window->top_vline);
if (unlikely(window->top_vline >= window->vlines_num))
window->top_vline = 0;
// int delta = ABS((int)window->vline_operating - (int)window->top_vline);
// 刷新所有行
textui_refresh_vlines(window, window->top_vline, window->vlines_num);
}
else
++window->vlines_used;
return 0;
}
static int __textui_putchar_window(struct textui_window_t *window, uint16_t character)
{
if (textui_is_chromatic(window->flags)) // 启用彩色字符
{
struct textui_vline_chromatic_t *vline = &window->vlines.chromatic[window->vline_operating];
vline->chars[vline->index].c = character;
vline->chars[vline->index].Fr = 0xff;
vline->chars[vline->index].Fg = 0xff;
vline->chars[vline->index].Fb = 0xff;
vline->chars[vline->index].Br = 0;
vline->chars[vline->index].Bg = 0;
vline->chars[vline->index].Bb = 0;
++vline->index;
textui_refresh_characters(window, window->vline_operating, vline->index - 1, 1);
// 换行
if (vline->index >= window->chars_per_line)
{
__textui_new_line(window, window->vline_operating);
}
}
else
{
// todo: 支持纯文本字符
while (1)
pause();
}
return 0;
}
/**
* @brief
*
* @param window
* @param character
* @return int
*/
int textui_putchar_window(struct textui_window_t *window, uint16_t character)
{
if (unlikely(character == '\0'))
return 0;
if (!textui_is_chromatic(window->flags)) // 暂不支持纯文本窗口
return 0;
uint64_t rflags = 0; // 加锁后rflags存储到这里
spin_lock_irqsave(&window->lock, rflags);
uart_send(COM1, character);
if (unlikely(character == '\n'))
{
__textui_new_line(window, window->vline_operating);
spin_unlock_irqrestore(&window->lock, rflags);
return 0;
}
else if (character == '\t') // 输出制表符
{
int space_to_print = 8 - window->vlines.chromatic[window->vline_operating].index % 8;
while (space_to_print--)
{
__textui_putchar_window(window, ' ');
}
}
else if (character == '\b') // 退格
{
--window->vlines.chromatic[window->vline_operating].index;
{
uint16_t tmp = window->vlines.chromatic[window->vline_operating].index;
window->vlines.chromatic[window->vline_operating].chars[tmp].c = ' ';
textui_refresh_characters(window, window->vline_operating, tmp, 1);
}
// 需要向上缩一行
if (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);
--window->vline_operating;
if (unlikely(window->vline_operating < 0))
window->vline_operating = window->vlines_num - 1;
// 考虑是否向上滚动
if (likely(window->vlines_used >= __private_info.actual_line))
{
--window->top_vline;
if (unlikely(window->top_vline < 0))
window->top_vline = window->vlines_num - 1;
}
--window->vlines_used;
textui_refresh_vlines(window, window->top_vline, __private_info.actual_line);
}
}
else
__textui_putchar_window(window, character);
spin_unlock_irqrestore(&window->lock, rflags);
return 0;
}
/**
* @brief
*
* @param character
* @return int
*/
int textui_putchar(uint16_t character)
{
return textui_putchar_window(__private_info.default_window, character);
}
/**
* @brief text ui框架
*
@ -48,14 +276,20 @@ struct scm_ui_framework_operations_t textui_ops =
*/
int textui_init()
{
memset(&textui_framework, 0, sizeof(textui_framework));
spin_init(&__window_id_lock);
__window_max_id = 0;
list_init(&__windows_list);
memset(&textui_framework, 0, sizeof(struct scm_ui_framework_t));
memset(&__private_info, 0, sizeof(struct textui_private_info_t));
io_mfence();
char name[] = "textUI";
strcpy(textui_framework.name, name);
textui_framework.ui_ops = &textui_ops;
textui_framework.type = SCM_FRAMWORK_TYPE_TEXT;
uart_send_str(COM1, "12121");
textui_framework.type = 0;
// 注册框架到屏幕管理器
int retval = scm_register(&textui_framework);
if (retval != 0)
{
@ -63,6 +297,26 @@ int textui_init()
while (1)
pause();
}
uint16_t chars_per_vline = textui_framework.buf->width / TEXTUI_CHAR_WIDTH;
uint16_t total_vlines = textui_framework.buf->height / TEXTUI_CHAR_HEIGHT;
int cnt = chars_per_vline * total_vlines;
struct textui_vline_chromatic_t *vl_ptr = __initial_vlines;
struct textui_char_chromatic_t *ch_ptr = __initial_chars;
// 初始化虚拟行
for (int i = 0; i < total_vlines; ++i)
{
__textui_init_vline((vl_ptr + i), (ch_ptr + i * chars_per_vline));
}
// 初始化窗口
__textui_init_window((&__initial_window), TEXTUI_WF_CHROMATIC, total_vlines, __initial_vlines, chars_per_vline);
__private_info.current_window = &__initial_window;
__private_info.default_window = &__initial_window;
__private_info.actual_line = textui_framework.buf->height / TEXTUI_CHAR_HEIGHT;
uart_send_str(COM1, "text ui initialized");
return 0;
}

View File

@ -1,4 +1,152 @@
#pragma once
#include <common/glib.h>
#include <common/sys/types.h>
#include <common/spinlock.h>
// 文本窗口标志位
// 文本窗口是否为彩色
#define TEXTUI_WF_CHROMATIC (1 << 0)
// 窗口是否启用彩色字符
#define textui_is_chromatic(flag) ((flag)&TEXTUI_WF_CHROMATIC)
// 每个字符的宽度和高度(像素)
#define TEXTUI_CHAR_WIDTH 8
#define TEXTUI_CHAR_HEIGHT 16
/**
* @brief
*
*/
struct textui_char_normal_t
{
char c;
};
/**
* @brief
*
*/
struct textui_char_chromatic_t
{
uint16_t c; // 字符
// 前景色
uint8_t Fr; // 红
uint8_t Fg; // 绿
uint8_t Fb; // 蓝
// 背景色
uint8_t Br;
uint8_t Bg;
uint8_t Bb;
};
// 注意!!! 请保持vline结构体的大小、成员变量命名相等
/**
* @brief
*
*/
struct textui_vline_normal_t
{
struct textui_char_normal_t *chars; // 字符对象数组
uint16_t index; // 当前操作的位置
};
/**
* @brief
*
*/
struct textui_vline_chromatic_t
{
struct textui_char_chromatic_t *chars;
uint16_t index; // 当前操作的位置
};
/**
* @brief textu ui
*
*/
struct textui_window_t
{
struct List list;
uint32_t id; // 窗口id
uint16_t vlines_num; // 虚拟行总数
uint16_t vlines_used; // 当前已经使用了的虚拟行总数
// 指向虚拟行的数组的指针(二选一)
union
{
struct textui_vline_normal_t *normal;
struct textui_vline_chromatic_t *chromatic;
} vlines;
uint16_t top_vline; // 位于最顶上的那一个虚拟行的行号
uint16_t vline_operating; // 正在操作的vline
uint16_t chars_per_line; // 每行最大容纳的字符数
uint8_t flags; // 窗口flag
spinlock_t lock; // 窗口操作锁
};
struct textui_private_info_t
{
uint16_t actual_line; // 真实行的数量
struct textui_window_t *current_window; // 当前的主窗口
struct textui_window_t *default_window; // 默认print到的窗口
};
/**
* @brief
*
* @param window
* @param vline_id
* @return int
*/
int textui_refresh_vline(struct textui_window_t *window, uint16_t vline_id);
int textui_refresh_vlines(struct textui_window_t *window, uint16_t start, uint16_t count);
/**
* @brief n个字符对象
*
* @param window
* @param vline_id
* @param start
* @param count
* @return int
*/
int textui_refresh_characters(struct textui_window_t *window, uint16_t vline_id, uint16_t start, uint16_t count);
/**
* @brief
*
* @param window
* @param character
* @return int
*/
int textui_putchar_window(struct textui_window_t *window, uint16_t character);
/**
* @brief
*
* @param character
* @return int
*/
int textui_putchar(uint16_t character);
/**
* @brief textui的帧缓冲区能容纳的内容的行数
*
* @return uint16_t
*/
uint16_t __textui_get_actual_lines();
/**
* @brief id
*
* @return uint16_t
*/
uint32_t __textui_get_current_window_id();
/**
* @brief text ui框架

View File

@ -76,11 +76,9 @@ void system_initialize()
scm_init();
textui_init();
kinfo("Kernel Starting...");
// kinfo("Kernel Starting...");
// 重新加载gdt和idt
ul tss_item_addr = (ul)phys_2_virt(0x7c00);
_stack_start = head_stack_start; // 保存init proc的栈基地址由于之后取消了地址重映射因此必须在这里重新保存
@ -100,6 +98,7 @@ void system_initialize()
// 初始化内存管理单元
mm_init();
// 内存管理单元初始化完毕后,需要立即重新初始化显示驱动。
// 原因是系统启动初期framebuffer被映射到48M地址处
// mm初始化完毕后若不重新初始化显示驱动将会导致错误的数据写入内存从而造成其他模块崩溃
@ -165,7 +164,6 @@ void system_initialize()
process_init();
// 启用double buffer
scm_enable_double_buffer();
io_mfence();
// fat32_init();
@ -175,6 +173,7 @@ void system_initialize()
// 系统初始化到此结束,剩下的初始化功能应当放在初始内核线程中执行
apic_timer_init();
io_mfence();
while(1);
}
//操作系统内核从这里开始执行