mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-09 07:06:47 +00:00
🆕 printk新增翻页滚动功能(bug:用户态触发中断时翻页会出现#UD)
This commit is contained in:
parent
12cc6a8375
commit
3961c0e1be
@ -20,15 +20,11 @@ bximage
|
|||||||
|
|
||||||
1. clone本项目
|
1. clone本项目
|
||||||
|
|
||||||
2. 在根目录下创建bin文件夹
|
2. 运行命令 bash run.sh
|
||||||
|
|
||||||
3. 将boot(empty).img复制到bin/,并重命名为boot.img
|
|
||||||
|
|
||||||
4. 使用sudo权限运行run_in_bochs.sh
|
|
||||||
|
|
||||||
## To do list:
|
## To do list:
|
||||||
|
|
||||||
- [x] bootloader
|
- [x] multiboot2
|
||||||
|
|
||||||
- [x] printk
|
- [x] printk
|
||||||
|
|
||||||
|
@ -44,6 +44,9 @@ typedef unsigned long long int ull;
|
|||||||
typedef long long int ll;
|
typedef long long int ll;
|
||||||
|
|
||||||
#define ABS(x) ((x) > 0 ? (x) : -(x)) // 绝对值
|
#define ABS(x) ((x) > 0 ? (x) : -(x)) // 绝对值
|
||||||
|
// 最大最小值
|
||||||
|
#define max(x, y) ((x > y) ? (x) : (y))
|
||||||
|
#define min(x, y) ((x < y) ? (x) : (y))
|
||||||
|
|
||||||
// 四舍五入成整数
|
// 四舍五入成整数
|
||||||
ul round(double x)
|
ul round(double x)
|
||||||
@ -60,7 +63,7 @@ ul round(double x)
|
|||||||
*/
|
*/
|
||||||
ul ALIGN(const ul addr, const ul _align)
|
ul ALIGN(const ul addr, const ul _align)
|
||||||
{
|
{
|
||||||
return (ul)((addr+_align-1)&(~(_align-1)));
|
return (ul)((addr + _align - 1) & (~(_align - 1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
//链表数据结构
|
//链表数据结构
|
||||||
@ -166,7 +169,7 @@ static inline int strlen(char *s)
|
|||||||
return __res;
|
return __res;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *memset(void *dst, unsigned char C, ul Count)
|
void *memset(void *dst, unsigned char C, ul size)
|
||||||
{
|
{
|
||||||
|
|
||||||
int d0, d1;
|
int d0, d1;
|
||||||
@ -185,7 +188,7 @@ void *memset(void *dst, unsigned char C, ul Count)
|
|||||||
"stosb \n\t"
|
"stosb \n\t"
|
||||||
"3: \n\t"
|
"3: \n\t"
|
||||||
: "=&c"(d0), "=&D"(d1)
|
: "=&c"(d0), "=&D"(d1)
|
||||||
: "a"(tmp), "q"(Count), "0"(Count / 8), "1"(dst)
|
: "a"(tmp), "q"(size), "0"(size / 8), "1"(dst)
|
||||||
: "memory");
|
: "memory");
|
||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
@ -2,30 +2,13 @@
|
|||||||
// Created by longjin on 2022/1/22.
|
// Created by longjin on 2022/1/22.
|
||||||
//
|
//
|
||||||
#include "printk.h"
|
#include "printk.h"
|
||||||
|
#include "kprint.h"
|
||||||
#include "../driver/multiboot2/multiboot2.h"
|
#include "../driver/multiboot2/multiboot2.h"
|
||||||
#include "../mm/mm.h"
|
#include "../mm/mm.h"
|
||||||
//#include "linkage.h"
|
//#include "linkage.h"
|
||||||
|
|
||||||
struct screen_info pos;
|
struct screen_info pos;
|
||||||
|
|
||||||
void show_color_band(int width, int height, char a, char b, char c, char d)
|
|
||||||
{
|
|
||||||
/** 向帧缓冲区写入像素值
|
|
||||||
* @param address: 帧缓存区的地址
|
|
||||||
* @param val:像素值
|
|
||||||
*/
|
|
||||||
|
|
||||||
for (int i = 0; i < width * height; ++i)
|
|
||||||
{
|
|
||||||
|
|
||||||
*((char *)pos.FB_address + 0) = d;
|
|
||||||
*((char *)pos.FB_address + 1) = c;
|
|
||||||
*((char *)pos.FB_address + 2) = b;
|
|
||||||
*((char *)pos.FB_address + 3) = a;
|
|
||||||
++pos.FB_address;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int calculate_max_charNum(int len, int size)
|
int calculate_max_charNum(int len, int size)
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
@ -33,7 +16,7 @@ int calculate_max_charNum(int len, int size)
|
|||||||
* @param len 屏幕长/宽
|
* @param len 屏幕长/宽
|
||||||
* @param size 字符长/宽
|
* @param size 字符长/宽
|
||||||
*/
|
*/
|
||||||
return len / size;
|
return len / size - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int init_printk(const int char_size_x, const int char_size_y)
|
int init_printk(const int char_size_x, const int char_size_y)
|
||||||
@ -51,10 +34,11 @@ int init_printk(const int char_size_x, const int char_size_y)
|
|||||||
|
|
||||||
// @todo:将来需要将帧缓冲区物理地址填写到这个地址的页表项中
|
// @todo:将来需要将帧缓冲区物理地址填写到这个地址的页表项中
|
||||||
pos.FB_address = 0xa00000;
|
pos.FB_address = 0xa00000;
|
||||||
pos.FB_length = pos.width*pos.height*4;
|
pos.FB_length = pos.width * pos.height;
|
||||||
|
|
||||||
pos.x = 0;
|
pos.x = 0;
|
||||||
pos.y = 0;
|
pos.y = 0;
|
||||||
|
cls();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -95,7 +79,12 @@ void auto_newline()
|
|||||||
++pos.y;
|
++pos.y;
|
||||||
}
|
}
|
||||||
if (pos.y > pos.max_y)
|
if (pos.y > pos.max_y)
|
||||||
pos.y = 0;
|
{
|
||||||
|
pos.y = pos.max_y;
|
||||||
|
int lines_to_scroll=2;
|
||||||
|
scroll(true, lines_to_scroll*pos.char_size_y, false);
|
||||||
|
pos.y-=lines_to_scroll;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int vsprintf(char *buf, const char *fmt, va_list args)
|
static int vsprintf(char *buf, const char *fmt, va_list args)
|
||||||
@ -646,6 +635,7 @@ int printk_color(unsigned int FRcolor, unsigned int BKcolor, const char *fmt, ..
|
|||||||
{
|
{
|
||||||
pos.x = 0;
|
pos.x = 0;
|
||||||
++pos.y;
|
++pos.y;
|
||||||
|
auto_newline();
|
||||||
}
|
}
|
||||||
else if (current == '\t') // 输出制表符
|
else if (current == '\t') // 输出制表符
|
||||||
{
|
{
|
||||||
@ -686,3 +676,110 @@ int printk_color(unsigned int FRcolor, unsigned int BKcolor, const char *fmt, ..
|
|||||||
|
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int do_scroll(bool direction, int pixels)
|
||||||
|
{
|
||||||
|
if (direction == true) // 向上滚动
|
||||||
|
{
|
||||||
|
pixels = pixels;
|
||||||
|
if (pixels > pos.height)
|
||||||
|
return EPOS_OVERFLOW;
|
||||||
|
// 无需滚动
|
||||||
|
if (pixels == 0)
|
||||||
|
return 0;
|
||||||
|
unsigned int src = pixels * pos.width;
|
||||||
|
unsigned int count = pos.FB_length - src;
|
||||||
|
|
||||||
|
memcpy(pos.FB_address, (pos.FB_address + src), sizeof(unsigned int)*(pos.FB_length - src));
|
||||||
|
memset(pos.FB_address+(pos.FB_length-src), 0, sizeof(unsigned int)*(src));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return EUNSUPPORTED;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @brief 滚动窗口(尚不支持向下滚动)
|
||||||
|
*
|
||||||
|
* @param direction 方向,向上滑动为true,否则为false
|
||||||
|
* @param pixels 要滑动的像素数量
|
||||||
|
* @param animation 是否包含滑动动画
|
||||||
|
*/
|
||||||
|
int scroll(bool direction, int pixels, bool animation)
|
||||||
|
{
|
||||||
|
// 暂时不支持反方向滚动
|
||||||
|
if (direction == false)
|
||||||
|
return EUNSUPPORTED;
|
||||||
|
// 为了保证打印字符正确,需要对pixel按照字体高度对齐
|
||||||
|
int md = pixels % pos.char_size_y;
|
||||||
|
if (md)
|
||||||
|
pixels = pixels + pos.char_size_y - md;
|
||||||
|
|
||||||
|
if (animation == false)
|
||||||
|
return do_scroll(direction, pixels);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int steps;
|
||||||
|
if (pixels > 10)
|
||||||
|
steps = 5;
|
||||||
|
else
|
||||||
|
steps = pixels % 5;
|
||||||
|
int half_steps = steps / 2;
|
||||||
|
|
||||||
|
// 计算加速度
|
||||||
|
double accelerate = 0.5 * pixels / (half_steps * half_steps);
|
||||||
|
int current_pixels = 0;
|
||||||
|
double delta_x;
|
||||||
|
|
||||||
|
int trace[13] = {0};
|
||||||
|
int js_trace = 0;
|
||||||
|
// 加速阶段
|
||||||
|
for (int i = 1; i <= half_steps; ++i)
|
||||||
|
{
|
||||||
|
trace[js_trace] = (int)(accelerate * i + 0.5);
|
||||||
|
current_pixels += trace[js_trace];
|
||||||
|
do_scroll(direction, trace[js_trace]);
|
||||||
|
|
||||||
|
++js_trace;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 强制使得位置位于1/2*pixels
|
||||||
|
if (current_pixels < pixels / 2)
|
||||||
|
{
|
||||||
|
delta_x = pixels / 2 - current_pixels;
|
||||||
|
do_scroll(direction, delta_x);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 减速阶段,是加速阶段的重放
|
||||||
|
for (int i = js_trace - 1; i >= 0; --i)
|
||||||
|
{
|
||||||
|
current_pixels += trace[i];
|
||||||
|
do_scroll(direction, trace[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (current_pixels > pixels)
|
||||||
|
kerror("During scrolling: scrolled pixels over bound!");
|
||||||
|
|
||||||
|
// 强制使得位置位于pixels
|
||||||
|
if (current_pixels < pixels)
|
||||||
|
{
|
||||||
|
delta_x = pixels - current_pixels;
|
||||||
|
do_scroll(direction, delta_x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 清屏
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int cls()
|
||||||
|
{
|
||||||
|
memset(pos.FB_address, BLACK, pos.FB_length * sizeof(unsigned int));
|
||||||
|
pos.x = 0;
|
||||||
|
pos.y = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
@ -29,6 +29,7 @@
|
|||||||
// 异常的宏定义
|
// 异常的宏定义
|
||||||
#define EPOS_OVERFLOW 1 // 坐标溢出
|
#define EPOS_OVERFLOW 1 // 坐标溢出
|
||||||
#define EFB_MISMATCH 2 // 帧缓冲区与指定的屏幕大小不匹配
|
#define EFB_MISMATCH 2 // 帧缓冲区与指定的屏幕大小不匹配
|
||||||
|
#define EUNSUPPORTED 3 // 当前操作暂不被支持
|
||||||
|
|
||||||
#include "font.h"
|
#include "font.h"
|
||||||
#include "glib.h"
|
#include "glib.h"
|
||||||
@ -118,3 +119,18 @@ static void putchar(unsigned int *fb, int Xsize, int x, int y, unsigned int FRco
|
|||||||
#define printk(...) printk_color( WHITE, BLACK, __VA_ARGS__ )
|
#define printk(...) printk_color( WHITE, BLACK, __VA_ARGS__ )
|
||||||
|
|
||||||
int printk_color(unsigned int FRcolor, unsigned int BKcolor, const char*fmt, ...);
|
int printk_color(unsigned int FRcolor, unsigned int BKcolor, const char*fmt, ...);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 滚动窗口(尚不支持向下滚动)
|
||||||
|
*
|
||||||
|
* @param direction 方向,向上滑动为true,否则为false
|
||||||
|
* @param pixels 要滑动的像素数量
|
||||||
|
* @param animation 是否包含滑动动画
|
||||||
|
*/
|
||||||
|
int scroll(bool direction, int pixels, bool animation);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 清屏
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int cls();
|
@ -85,6 +85,8 @@ void system_initialize()
|
|||||||
// 先初始化系统调用模块
|
// 先初始化系统调用模块
|
||||||
syscall_init();
|
syscall_init();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 再初始化进程模块。顺序不能调转
|
// 再初始化进程模块。顺序不能调转
|
||||||
process_init();
|
process_init();
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,6 @@ void __switch_to(struct process_control_block *prev, struct process_control_bloc
|
|||||||
__asm__ __volatile__("movq %0, %%gs \n\t" ::"a"(next->thread->gs));
|
__asm__ __volatile__("movq %0, %%gs \n\t" ::"a"(next->thread->gs));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 这是一个用户态的程序
|
* @brief 这是一个用户态的程序
|
||||||
*
|
*
|
||||||
@ -39,13 +38,13 @@ void user_level_function()
|
|||||||
{
|
{
|
||||||
kinfo("Program (user_level_function) is runing...");
|
kinfo("Program (user_level_function) is runing...");
|
||||||
kinfo("Try to enter syscall id 15...");
|
kinfo("Try to enter syscall id 15...");
|
||||||
enter_syscall(15,0,0,0,0,0,0,0,0);
|
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);
|
||||||
|
|
||||||
enter_syscall(SYS_PRINTF, (ul)"test_sys_printf\n", 0,0,0,0,0,0,0);
|
|
||||||
kinfo("Return from syscall id 15...");
|
kinfo("Return from syscall id 15...");
|
||||||
|
|
||||||
|
while (1)
|
||||||
while(1);
|
;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @brief 使当前进程去执行新的代码
|
* @brief 使当前进程去执行新的代码
|
||||||
@ -201,8 +200,6 @@ void process_init()
|
|||||||
|
|
||||||
initial_mm.stack_start = _stack_start;
|
initial_mm.stack_start = _stack_start;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 初始化进程和tss
|
// 初始化进程和tss
|
||||||
set_TSS64(initial_thread.rbp, initial_tss[0].rsp1, initial_tss[0].rsp2, initial_tss[0].ist1, initial_tss[0].ist2, initial_tss[0].ist3, initial_tss[0].ist4, initial_tss[0].ist5, initial_tss[0].ist6, initial_tss[0].ist7);
|
set_TSS64(initial_thread.rbp, initial_tss[0].rsp1, initial_tss[0].rsp2, initial_tss[0].ist1, initial_tss[0].ist2, initial_tss[0].ist3, initial_tss[0].ist4, initial_tss[0].ist5, initial_tss[0].ist6, initial_tss[0].ist7);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user