This commit is contained in:
catfood 2022-12-23 23:22:37 +08:00
commit 4bd7c1e46d
9 changed files with 1546 additions and 1145 deletions

View File

@ -1,4 +1,4 @@
/*************************************************************************//** /*************************************************************************/ /**
***************************************************************************** *****************************************************************************
* @file console.h * @file console.h
* @brief * @brief
@ -8,13 +8,12 @@
*****************************************************************************/ *****************************************************************************/
/********************************************************** /**********************************************************
* console.h //added by mingxuan 2019-5-17 * console.h //added by mingxuan 2019-5-17
***********************************************************/ ***********************************************************/
#ifndef _ORANGES_CONSOLE_H_ #ifndef _ORANGES_CONSOLE_H_
#define _ORANGES_CONSOLE_H_ #define _ORANGES_CONSOLE_H_
/* CONSOLE */ /* CONSOLE */
typedef struct s_console typedef struct s_console
{ {
@ -24,8 +23,7 @@ typedef struct s_console
unsigned int cursor; unsigned int cursor;
int is_full; int is_full;
unsigned int current_line; unsigned int current_line;
}CONSOLE; } CONSOLE;
#define SCR_UP 1 /* scroll upward */ #define SCR_UP 1 /* scroll upward */
#define SCR_DN -1 /* scroll downward */ #define SCR_DN -1 /* scroll downward */
@ -33,13 +31,13 @@ typedef struct s_console
#define SCR_WIDTH 80 #define SCR_WIDTH 80
#define SCR_HEIGHT 25 #define SCR_HEIGHT 25
#define SCR_SIZE (SCR_HEIGHT * SCR_WIDTH) #define SCR_SIZE (SCR_HEIGHT * SCR_WIDTH)
#define SCR_BUFSIZE (8 * SCR_SIZE) #define SCR_BUFSIZE (2 * SCR_SIZE)
#define SCR_MAXLINE (SCR_BUFSIZE / SCR_WIDTH) #define SCR_MAXLINE (SCR_BUFSIZE / SCR_WIDTH)
#define DEFAULT_CHAR_COLOR (MAKE_COLOR(BLACK, WHITE | BRIGHT)) #define DEFAULT_CHAR_COLOR ((MAKE_COLOR(BLACK, WHITE | BRIGHT)) << 8)
#define GRAY_CHAR (MAKE_COLOR(BLACK, BLACK) | BRIGHT) #define GRAY_CHAR (MAKE_COLOR(BLACK, BLACK) | BRIGHT)
#define RED_CHAR (MAKE_COLOR(BLUE, RED) | BRIGHT) #define RED_CHAR (MAKE_COLOR(BLUE, RED) | BRIGHT)
#define MAKE_CELL(clr, ch) ((clr << 8) | ch) #define MAKE_CELL(clr, ch) (clr | ch)
#define BLANK MAKE_CELL(DEFAULT_CHAR_COLOR, ' ') #define BLANK MAKE_CELL(DEFAULT_CHAR_COLOR, ' ')
#endif /* _ORANGES_CONSOLE_H_ */ #endif /* _ORANGES_CONSOLE_H_ */

View File

@ -1,4 +1,4 @@
/*************************************************************************//** /*************************************************************************/ /**
***************************************************************************** *****************************************************************************
* @file tty.h * @file tty.h
* @brief * @brief
@ -8,13 +8,12 @@
*****************************************************************************/ *****************************************************************************/
/********************************************************** /**********************************************************
* tty.h //added by mingxuan 2019-5-17 * tty.h //added by mingxuan 2019-5-17
***********************************************************/ ***********************************************************/
#ifndef _ORANGES_TTY_H_ #ifndef _ORANGES_TTY_H_
#define _ORANGES_TTY_H_ #define _ORANGES_TTY_H_
#define TTY_IN_BYTES 256 /* tty input queue size */ #define TTY_IN_BYTES 256 /* tty input queue size */
#define TTY_OUT_BUF_LEN 2 /* tty output buffer size */ #define TTY_OUT_BUF_LEN 2 /* tty output buffer size */
@ -34,9 +33,9 @@ struct s_console;
typedef struct s_tty typedef struct s_tty
{ {
u32 ibuf[TTY_IN_BYTES]; /* TTY input buffer */ u32 ibuf[TTY_IN_BYTES]; /* TTY input buffer */
u32* ibuf_head; /* the next free slot */ u32 *ibuf_head; /* the next free slot */
u32* ibuf_tail; /* 缓冲区显示位置指针 */ u32 *ibuf_tail; /* 缓冲区显示位置指针 */
u32* ibuf_read; u32 *ibuf_read;
int ibuf_cnt; /* how many */ int ibuf_cnt; /* how many */
int ibuf_read_cnt; int ibuf_read_cnt;
int status; int status;
@ -46,10 +45,11 @@ typedef struct s_tty
int mouse_X; int mouse_X;
int mouse_Y; int mouse_Y;
struct s_console * console; struct s_console *console;
}TTY; } TTY;
typedef struct MouseState{ typedef struct MouseState
{
u8 mouse_lb; u8 mouse_lb;
u8 mouse_mb; u8 mouse_mb;
u8 mouse_rb; u8 mouse_rb;
@ -58,21 +58,35 @@ typedef struct MouseState{
int mouse_y; int mouse_y;
} MouseState; } MouseState;
typedef struct n_tty { typedef struct n_tty
{
int driver_type; // 1-vga&kbd; 2-serial int driver_type; // 1-vga&kbd; 2-serial
MouseState mouse; MouseState mouse;
void* input_buf; void *input_buf;
void* output_buf; void *output_buf;
} NTTY; } NTTY;
typedef struct vga_buf { enum CSI_state
void* buf; // 2d array, screen size, for text mode it's [maxline][80] {
CSI_ESC,
CSI_BRACKET,
CSI_PARAM1,
CSI_PARAM2
};
typedef struct vga_buf
{
void *buf; // 2d array, screen size, for text mode it's [maxline][80]
int max_line; // to support scroll, max line should be a lot more than screen int max_line; // to support scroll, max line should be a lot more than screen
int scr_top_line; // the index in buf of top line on screen; int scr_top_line; // the index in buf of top line on screen;
int scr_cur_line; // the index in buf of the cursor's line int scr_cur_line; // the index in buf of the cursor's line
int head_line; // for circular buffer use int head_line; // for circular buffer use
int cur_row; int cur_row;
int cur_col; // cursor position, on screen int cur_col; // cursor position, on screen
enum CSI_state CSI;
i16 param1; // the first param of CSI
i16 param2; // the second of CSI
u16 color;
} vga_buf; } vga_buf;
typedef struct keyboard_buf { typedef struct keyboard_buf {
@ -86,9 +100,9 @@ typedef struct keyboard_buf {
#include "console.h" #include "console.h"
void select_console(int nr_console); void select_console(int nr_console);
void init_screen(TTY* tty); void init_screen(TTY *tty);
void out_char(CONSOLE* con, char ch); void out_char(CONSOLE *con, char ch);
int is_current_console(CONSOLE* con); int is_current_console(CONSOLE *con);
int init_serial(); int init_serial();
char read_serial(); char read_serial();
@ -106,6 +120,9 @@ int ps2_tty_read(NTTY* tty, u8* buf, int nr);
#define NEXT(x, _max) (((x) + 1) % (_max)) #define NEXT(x, _max) (((x) + 1) % (_max))
#define LAST(x, _max) (((x) - 1) >= 0 ? ((x) - 1) % (_max) : (_max) - 1) #define LAST(x, _max) (((x) - 1) >= 0 ? ((x) - 1) % (_max) : (_max) - 1)
#define DEBUGNEW #define DEBUGNEW
#define FOREGROUND(color) ((u16)(color & 0xf) << 8)
#define BACKGROUND(color) ((u16)(color & 0xf) << 12)
extern int cur_ntty; extern int cur_ntty;
extern NTTY ntty_table[3]; extern NTTY ntty_table[3];
#endif /* _ORANGES_TTY_H_ */ #endif /* _ORANGES_TTY_H_ */

View File

@ -15,10 +15,10 @@
/* local routines */ /* local routines */
static void set_cursor(unsigned int position); static void set_cursor(unsigned int position);
static void set_video_start_addr(u32 addr); static void set_video_start_addr(u32 addr);
static void flush(CONSOLE* con); static void flush(CONSOLE *con);
static void w_copy(unsigned int dst, const unsigned int src, int size); static void w_copy(unsigned int dst, const unsigned int src, int size);
static void clear_screen(int pos, int len); static void clear_screen(int pos, int len);
void scroll_screen(CONSOLE* con, int dir); void scroll_screen(CONSOLE *con, int dir);
/***************************************************************************** /*****************************************************************************
* init_screen * init_screen
@ -28,7 +28,7 @@ void scroll_screen(CONSOLE* con, int dir);
* *
* @param tty Whose console is to be initialized. * @param tty Whose console is to be initialized.
*****************************************************************************/ *****************************************************************************/
void init_screen(TTY* tty) void init_screen(TTY *tty)
{ {
int nr_tty = tty - tty_table; int nr_tty = tty - tty_table;
@ -40,29 +40,31 @@ void init_screen(TTY* tty)
* in WORDs, but not in BYTEs. * in WORDs, but not in BYTEs.
*/ */
int v_mem_size = V_MEM_SIZE >> 1; /* size of Video Memory */ int v_mem_size = V_MEM_SIZE >> 1; /* size of Video Memory */
int size_per_con = (v_mem_size / NR_CONSOLES)/80*80; int size_per_con = (v_mem_size / NR_CONSOLES) / 80 * 80;
tty->console->orig = nr_tty * size_per_con; tty->console->orig = nr_tty * size_per_con;
tty->console->con_size = size_per_con / SCR_WIDTH * SCR_WIDTH; tty->console->con_size = size_per_con / SCR_WIDTH * SCR_WIDTH;
tty->console->cursor = tty->console->crtc_start = tty->console->orig; tty->console->cursor = tty->console->crtc_start = tty->console->orig;
tty->console->is_full = 0; tty->console->is_full = 0;
tty->console->current_line = 0; tty->console->current_line = 0;
if(nr_tty==0){ if (nr_tty == 0)
{
tty->console->cursor = disp_pos / 2; tty->console->cursor = disp_pos / 2;
} }
const char prompt[] = "[TTY #?]\n"; const char prompt[] = "[TTY #?]\n";
const char * p = prompt; const char *p = prompt;
for (; *p; p++){ for (; *p; p++)
{
out_char(tty->console, *p == '?' ? nr_tty + '0' : *p); out_char(tty->console, *p == '?' ? nr_tty + '0' : *p);
} }
set_cursor(tty->console->cursor); set_cursor(tty->console->cursor);
} }
static inline void write_char_c(int pos, char ch)
static inline void write_char_c(int pos, char ch) { {
u16* pch = (u16*)K_PHY2LIN(V_MEM_BASE + pos);\ u16 *pch = (u16 *)K_PHY2LIN(V_MEM_BASE + pos);
*pch = (0x0f << 8) | ch; *pch = (0x0f << 8) | ch;
} }
@ -76,23 +78,25 @@ static inline void write_char_c(int pos, char ch) {
* @param ch The char to print. * @param ch The char to print.
*****************************************************************************/ *****************************************************************************/
void out_char(CONSOLE* con, char ch) void out_char(CONSOLE *con, char ch)
{ {
disable_int(); disable_int();
int cursor_x = (con->cursor - con->orig) % SCR_WIDTH; int cursor_x = (con->cursor - con->orig) % SCR_WIDTH;
int cursor_y = (con->cursor - con->orig) / SCR_WIDTH; int cursor_y = (con->cursor - con->orig) / SCR_WIDTH;
switch(ch) { switch (ch)
{
case '\n': case '\n':
con->cursor = con->orig + SCR_WIDTH * (cursor_y + 1); con->cursor = con->orig + SCR_WIDTH * (cursor_y + 1);
break; break;
case '\b': case '\b':
if (con->cursor > con->orig) { if (con->cursor > con->orig)
{
con->cursor--; con->cursor--;
//*(pch - 2) = ' '; //*(pch - 2) = ' ';
//*(pch - 1) = DEFAULT_CHAR_COLOR; //*(pch - 1) = DEFAULT_CHAR_COLOR;
disp_pos = con->cursor*2; disp_pos = con->cursor * 2;
// write_char(' '); // write_char(' ');
write_char_c(disp_pos, ' '); write_char_c(disp_pos, ' ');
} }
@ -100,7 +104,7 @@ void out_char(CONSOLE* con, char ch)
default: default:
//*pch++ = ch; //*pch++ = ch;
//*pch++ = DEFAULT_CHAR_COLOR; //*pch++ = DEFAULT_CHAR_COLOR;
disp_pos = con->cursor*2; disp_pos = con->cursor * 2;
// write_char(ch); // write_char(ch);
write_char_c(disp_pos, ch); write_char_c(disp_pos, ch);
con->cursor++; con->cursor++;
@ -108,9 +112,8 @@ void out_char(CONSOLE* con, char ch)
break; break;
} }
if (con->cursor - con->orig >= con->con_size)
{
if (con->cursor - con->orig >= con->con_size) {
cursor_x = (con->cursor - con->orig) % SCR_WIDTH; cursor_x = (con->cursor - con->orig) % SCR_WIDTH;
cursor_y = (con->cursor - con->orig) / SCR_WIDTH; cursor_y = (con->cursor - con->orig) / SCR_WIDTH;
int cp_orig = con->orig + (cursor_y + 1) * SCR_WIDTH - SCR_SIZE; int cp_orig = con->orig + (cursor_y + 1) * SCR_WIDTH - SCR_SIZE;
@ -122,10 +125,11 @@ void out_char(CONSOLE* con, char ch)
con->is_full = 1; con->is_full = 1;
} }
//assert(con->cursor - con->orig < con->con_size); // assert(con->cursor - con->orig < con->con_size);
while (con->cursor >= con->crtc_start + SCR_SIZE || while (con->cursor >= con->crtc_start + SCR_SIZE ||
con->cursor < con->crtc_start) { con->cursor < con->crtc_start)
{
scroll_screen(con, SCR_UP); scroll_screen(con, SCR_UP);
clear_screen(con->cursor, SCR_WIDTH); clear_screen(con->cursor, SCR_WIDTH);
@ -136,7 +140,6 @@ void out_char(CONSOLE* con, char ch)
enable_int(); enable_int();
} }
/***************************************************************************** /*****************************************************************************
* clear_screen * clear_screen
*****************************************************************************/ *****************************************************************************/
@ -148,14 +151,14 @@ void out_char(CONSOLE* con, char ch)
*****************************************************************************/ *****************************************************************************/
static void clear_screen(int pos, int len) static void clear_screen(int pos, int len)
{ {
u8 * pch = (u8*)K_PHY2LIN(V_MEM_BASE + pos * 2); u8 *pch = (u8 *)K_PHY2LIN(V_MEM_BASE + pos * 2);
while (--len >= 0) { while (--len >= 0)
{
*pch++ = ' '; *pch++ = ' ';
*pch++ = DEFAULT_CHAR_COLOR; *pch++ = (u8)(DEFAULT_CHAR_COLOR >> 8);
} }
} }
/***************************************************************************** /*****************************************************************************
* is_current_console * is_current_console
*****************************************************************************/ *****************************************************************************/
@ -166,12 +169,11 @@ static void clear_screen(int pos, int len)
* *
* @return TRUE if con is the current console. * @return TRUE if con is the current console.
*****************************************************************************/ *****************************************************************************/
int is_current_console(CONSOLE* con) int is_current_console(CONSOLE *con)
{ {
return (con == &console_table[current_console]); return (con == &console_table[current_console]);
} }
/***************************************************************************** /*****************************************************************************
* set_cursor * set_cursor
*****************************************************************************/ *****************************************************************************/
@ -191,7 +193,6 @@ static void set_cursor(unsigned int position)
enable_int(); enable_int();
} }
/***************************************************************************** /*****************************************************************************
* set_video_start_addr * set_video_start_addr
*****************************************************************************/ *****************************************************************************/
@ -210,7 +211,6 @@ static void set_video_start_addr(u32 addr)
enable_int(); enable_int();
} }
/***************************************************************************** /*****************************************************************************
* select_console * select_console
*****************************************************************************/ *****************************************************************************/
@ -221,12 +221,12 @@ static void set_video_start_addr(u32 addr)
*****************************************************************************/ *****************************************************************************/
void select_console(int nr_console) void select_console(int nr_console)
{ {
if ((nr_console < 0) || (nr_console >= NR_CONSOLES)) return; if ((nr_console < 0) || (nr_console >= NR_CONSOLES))
return;
flush(&console_table[current_console = nr_console]); flush(&console_table[current_console = nr_console]);
} }
/***************************************************************************** /*****************************************************************************
* scroll_screen * scroll_screen
*****************************************************************************/ *****************************************************************************/
@ -246,56 +246,65 @@ void select_console(int nr_console)
* @param dir SCR_UP : scroll the screen upwards; * @param dir SCR_UP : scroll the screen upwards;
* SCR_DN : scroll the screen downwards * SCR_DN : scroll the screen downwards
*****************************************************************************/ *****************************************************************************/
void scroll_screen(CONSOLE* con, int dir) void scroll_screen(CONSOLE *con, int dir)
{ {
/* /*
* variables below are all in-console-offsets (based on con->orig) * variables below are all in-console-offsets (based on con->orig)
*/ */
int oldest; /* addr of the oldest available line in the console */ int oldest; /* addr of the oldest available line in the console */
int newest; /* .... .. ... latest ......... .... .. ... ....... */ int newest; /* .... .. ... latest ......... .... .. ... ....... */
int scr_top;/* position of the top of current screen */ int scr_top; /* position of the top of current screen */
newest = (con->cursor - con->orig) / SCR_WIDTH * SCR_WIDTH; newest = (con->cursor - con->orig) / SCR_WIDTH * SCR_WIDTH;
oldest = con->is_full ? (newest + SCR_WIDTH) % con->con_size : 0; oldest = con->is_full ? (newest + SCR_WIDTH) % con->con_size : 0;
scr_top = con->crtc_start - con->orig; scr_top = con->crtc_start - con->orig;
if (dir == SCR_DN) { if (dir == SCR_DN)
if (!con->is_full && scr_top > 0) { {
if (!con->is_full && scr_top > 0)
{
con->crtc_start -= SCR_WIDTH; con->crtc_start -= SCR_WIDTH;
} }
else if (con->is_full && scr_top != oldest) { else if (con->is_full && scr_top != oldest)
if (con->cursor - con->orig >= con->con_size - SCR_SIZE) { {
if (con->cursor - con->orig >= con->con_size - SCR_SIZE)
{
if (con->crtc_start != con->orig) if (con->crtc_start != con->orig)
con->crtc_start -= SCR_WIDTH; con->crtc_start -= SCR_WIDTH;
} }
else if (con->crtc_start == con->orig) { else if (con->crtc_start == con->orig)
{
scr_top = con->con_size - SCR_SIZE; scr_top = con->con_size - SCR_SIZE;
con->crtc_start = con->orig + scr_top; con->crtc_start = con->orig + scr_top;
} }
else { else
{
con->crtc_start -= SCR_WIDTH; con->crtc_start -= SCR_WIDTH;
} }
} }
} }
else if (dir == SCR_UP) { else if (dir == SCR_UP)
if (!con->is_full && newest >= scr_top + SCR_SIZE) { {
if (!con->is_full && newest >= scr_top + SCR_SIZE)
{
con->crtc_start += SCR_WIDTH; con->crtc_start += SCR_WIDTH;
} }
else if (con->is_full && scr_top + SCR_SIZE - SCR_WIDTH != newest) { else if (con->is_full && scr_top + SCR_SIZE - SCR_WIDTH != newest)
{
if (scr_top + SCR_SIZE == con->con_size) if (scr_top + SCR_SIZE == con->con_size)
con->crtc_start = con->orig; con->crtc_start = con->orig;
else else
con->crtc_start += SCR_WIDTH; con->crtc_start += SCR_WIDTH;
} }
} }
else { else
//assert(dir == SCR_DN || dir == SCR_UP); {
// assert(dir == SCR_DN || dir == SCR_UP);
} }
flush(con); flush(con);
} }
/***************************************************************************** /*****************************************************************************
* flush * flush
*****************************************************************************/ *****************************************************************************/
@ -305,9 +314,10 @@ void scroll_screen(CONSOLE* con, int dir)
* *
* @param con The console to be set. * @param con The console to be set.
*****************************************************************************/ *****************************************************************************/
static void flush(CONSOLE* con) static void flush(CONSOLE *con)
{ {
if (is_current_console(con)) { if (is_current_console(con))
{
set_cursor(con->cursor); set_cursor(con->cursor);
set_video_start_addr(con->crtc_start); set_video_start_addr(con->crtc_start);
} }
@ -328,7 +338,7 @@ static void flush(CONSOLE* con)
*****************************************************************************/ *****************************************************************************/
static void w_copy(unsigned int dst, const unsigned int src, int size) static void w_copy(unsigned int dst, const unsigned int src, int size)
{ {
memcpy((void*)(V_MEM_BASE + (dst << 1)), memcpy((void *)(V_MEM_BASE + (dst << 1)),
(void*)(V_MEM_BASE + (src << 1)), (void *)(V_MEM_BASE + (src << 1)),
size << 1); size << 1);
} }

File diff suppressed because it is too large Load Diff

View File

@ -23,8 +23,8 @@
#include "stdio.h" #include "stdio.h"
#include "tty.h" #include "tty.h"
static int initialize_processes(); //added by xw, 18/5/26 static int initialize_processes(); // added by xw, 18/5/26
static int initialize_cpus(); //added by xw, 18/6/2 static int initialize_cpus(); // added by xw, 18/6/2
/*======================================================================* /*======================================================================*
kernel_main kernel_main
@ -43,23 +43,23 @@ int kernel_main()
disp_pos = 0; disp_pos = 0;
kprintf("-----Kernel Initialization Begins-----\n"); kprintf("-----Kernel Initialization Begins-----\n");
kernel_initial = 1; //kernel is in initial state. added by xw, 18/5/31 kernel_initial = 1; // kernel is in initial state. added by xw, 18/5/31
init();//内存管理模块的初始化 add by liang init(); // 内存管理模块的初始化 add by liang
init_tty_main(); init_tty_main();
//initialize PCBs, added by xw, 18/5/26 // initialize PCBs, added by xw, 18/5/26
error = initialize_processes(); error = initialize_processes();
if(error != 0) if (error != 0)
return error; return error;
//initialize CPUs, added by xw, 18/6/2 // initialize CPUs, added by xw, 18/6/2
error = initialize_cpus(); error = initialize_cpus();
if(error != 0) if (error != 0)
return error; return error;
k_reenter = 0; //record nest level of only interruption! it's different from Orange's. k_reenter = 0; // record nest level of only interruption! it's different from Orange's.
//usage modified by xw // usage modified by xw
ticks = 0; //initialize system-wide ticks ticks = 0; // initialize system-wide ticks
p_proc_current = cpu_table; p_proc_current = cpu_table;
/************************************************************************ /************************************************************************
@ -68,14 +68,14 @@ int kernel_main()
*************************************************************************/ *************************************************************************/
/* initialize 8253 PIT */ /* initialize 8253 PIT */
outb(TIMER_MODE, RATE_GENERATOR); outb(TIMER_MODE, RATE_GENERATOR);
outb(TIMER0, (u8) (TIMER_FREQ/HZ) ); outb(TIMER0, (u8)(TIMER_FREQ / HZ));
outb(TIMER0, (u8) ((TIMER_FREQ/HZ) >> 8)); outb(TIMER0, (u8)((TIMER_FREQ / HZ) >> 8));
/* initialize clock-irq */ /* initialize clock-irq */
put_irq_handler(CLOCK_IRQ, clock_handler); /* 设定时钟中断处理程序 */ put_irq_handler(CLOCK_IRQ, clock_handler); /* 设定时钟中断处理程序 */
enable_irq(CLOCK_IRQ); /* 让8259A可以接收时钟中断 */ enable_irq(CLOCK_IRQ); /* 让8259A可以接收时钟中断 */
init_kb(); //added by mingxuan 2019-5-19 init_kb(); // added by mingxuan 2019-5-19
/* initialize hd-irq and hd rdwt queue */ /* initialize hd-irq and hd rdwt queue */
init_hd(); init_hd();
@ -90,15 +90,15 @@ int kernel_main()
open hard disk and initialize file system open hard disk and initialize file system
coded by zcr on 2017.6.10. added by xw, 18/5/31 coded by zcr on 2017.6.10. added by xw, 18/5/31
************************************************************************/ ************************************************************************/
init_fileop_table(); //added by mingxuan 2019-5-17 init_fileop_table(); // added by mingxuan 2019-5-17
//hd_open(MINOR(ROOT_DEV)); // hd_open(MINOR(ROOT_DEV));
hd_open(PRIMARY_MASTER); //modified by mingxuan 2020-10-27 hd_open(PRIMARY_MASTER); // modified by mingxuan 2020-10-27
init_vfs(); //added by mingxuan 2020-10-30 init_vfs(); // added by mingxuan 2020-10-30
init_fs(); init_fs();
init_fs_fat(); //added by mingxuan 2019-5-17 init_fs_fat(); // added by mingxuan 2019-5-17
//init_vfs(); //added by mingxuan 2019-5-17 //deleted by mingxuan 2020-10-30 // init_vfs(); //added by mingxuan 2019-5-17 //deleted by mingxuan 2020-10-30
/************************************************************************* /*************************************************************************
* *
@ -117,9 +117,11 @@ int kernel_main()
clear_kernel_pagepte_low(); clear_kernel_pagepte_low();
p_proc_current = proc_table; p_proc_current = proc_table;
kernel_initial = 0; //kernel initialization is done. added by xw, 18/5/31 kernel_initial = 0; // kernel initialization is done. added by xw, 18/5/31
restart_initial(); //modified by xw, 18/4/19 restart_initial(); // modified by xw, 18/4/19
while(1){} while (1)
{
}
} }
/************************************************************************* /*************************************************************************
@ -128,8 +130,8 @@ added by xw, 18/6/2
***************************************************************************/ ***************************************************************************/
static int initialize_cpus() static int initialize_cpus()
{ {
//just use the fields of struct PCB in cpu_table, we needn't initialize // just use the fields of struct PCB in cpu_table, we needn't initialize
//something at present. // something at present.
return 0; return 0;
} }
@ -141,316 +143,311 @@ moved from kernel_main() by xw, 18/5/26
***************************************************************************/ ***************************************************************************/
static int initialize_processes() static int initialize_processes()
{ {
TASK* p_task = task_table; TASK *p_task = task_table;
PROCESS* p_proc = proc_table; PROCESS *p_proc = proc_table;
u16 selector_ldt = SELECTOR_LDT_FIRST; u16 selector_ldt = SELECTOR_LDT_FIRST;
char* p_regs; //point to registers in the new kernel stack, added by xw, 17/12/11 char *p_regs; // point to registers in the new kernel stack, added by xw, 17/12/11
task_f eip_context; //a funtion pointer, added by xw, 18/4/18 task_f eip_context; // a funtion pointer, added by xw, 18/4/18
/************************************************************************* /*************************************************************************
* edit by visual 2016.5.4 * edit by visual 2016.5.4
***************************************************************************/ ***************************************************************************/
int pid; int pid;
u32 AddrLin,err_temp;//edit by visual 2016.5.9 u32 AddrLin, err_temp; // edit by visual 2016.5.9
/* set common fields in PCB. added by xw, 18/5/25 */ /* set common fields in PCB. added by xw, 18/5/25 */
p_proc = proc_table; p_proc = proc_table;
for( pid=0 ; pid<NR_PCBS ; pid++ ) for (pid = 0; pid < NR_PCBS; pid++)
{ {
//some operations // some operations
p_proc++; p_proc++;
} }
p_proc = proc_table; p_proc = proc_table;
for( pid=0 ; pid<NR_TASKS ; pid++ ) for (pid = 0; pid < NR_TASKS; pid++)
{//1>对前NR_TASKS个PCB初始化,且状态为READY(生成的进程) { // 1>对前NR_TASKS个PCB初始化,且状态为READY(生成的进程)
/*************基本信息*********************************/ /*************基本信息*********************************/
strcpy(p_proc->task.p_name, p_task->name); //名称 strcpy(p_proc->task.p_name, p_task->name); // 名称
p_proc->task.pid = pid; //pid p_proc->task.pid = pid; // pid
p_proc->task.stat = READY; //状态 p_proc->task.stat = READY; // 状态
/**************LDT*********************************/ /**************LDT*********************************/
p_proc->task.ldt_sel = selector_ldt; p_proc->task.ldt_sel = selector_ldt;
memcpy(&p_proc->task.ldts[0], &gdt[SELECTOR_KERNEL_CS >> 3],sizeof(DESCRIPTOR)); memcpy(&p_proc->task.ldts[0], &gdt[SELECTOR_KERNEL_CS >> 3], sizeof(DESCRIPTOR));
p_proc->task.ldts[0].attr1 = DA_C | PRIVILEGE_TASK << 5; p_proc->task.ldts[0].attr1 = DA_C | PRIVILEGE_TASK << 5;
memcpy(&p_proc->task.ldts[1], &gdt[SELECTOR_KERNEL_DS >> 3],sizeof(DESCRIPTOR)); memcpy(&p_proc->task.ldts[1], &gdt[SELECTOR_KERNEL_DS >> 3], sizeof(DESCRIPTOR));
p_proc->task.ldts[1].attr1 = DA_DRW | PRIVILEGE_TASK << 5; p_proc->task.ldts[1].attr1 = DA_DRW | PRIVILEGE_TASK << 5;
/**************寄存器初值**********************************/ /**************寄存器初值**********************************/
p_proc->task.regs.cs = ((8 * 0) & SA_RPL_MASK & SA_TI_MASK)| SA_TIL | RPL_TASK; p_proc->task.regs.cs = ((8 * 0) & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_TASK;
p_proc->task.regs.ds = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK)| SA_TIL | RPL_TASK; p_proc->task.regs.ds = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_TASK;
p_proc->task.regs.es = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK)| SA_TIL | RPL_TASK; p_proc->task.regs.es = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_TASK;
p_proc->task.regs.fs = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK)| SA_TIL | RPL_TASK; p_proc->task.regs.fs = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_TASK;
p_proc->task.regs.ss = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK)| SA_TIL | RPL_TASK; p_proc->task.regs.ss = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_TASK;
p_proc->task.regs.gs = (SELECTOR_KERNEL_GS & SA_RPL_MASK)| RPL_TASK; p_proc->task.regs.gs = (SELECTOR_KERNEL_GS & SA_RPL_MASK) | RPL_TASK;
p_proc->task.regs.eflags = 0x1202; /* IF=1, IOPL=1 */ p_proc->task.regs.eflags = 0x1202; /* IF=1, IOPL=1 */
//p_proc->task.cr3 在页表初始化中处理 // p_proc->task.cr3 在页表初始化中处理
/**************线性地址布局初始化**********************************/ // add by visual 2016.5.4
/**************线性地址布局初始化**********************************/// add by visual 2016.5.4
/**************task的代码数据大小及位置暂时是不会用到的所以没有初始化************************************/ /**************task的代码数据大小及位置暂时是不会用到的所以没有初始化************************************/
p_proc->task.memmap.heap_lin_base = HeapLinBase; p_proc->task.memmap.heap_lin_base = HeapLinBase;
p_proc->task.memmap.heap_lin_limit = HeapLinBase; //堆的界限将会一直动态变化 p_proc->task.memmap.heap_lin_limit = HeapLinBase; // 堆的界限将会一直动态变化
p_proc->task.memmap.stack_child_limit = StackLinLimitMAX; //add by visual 2016.5.27 p_proc->task.memmap.stack_child_limit = StackLinLimitMAX; // add by visual 2016.5.27
p_proc->task.memmap.stack_lin_base = StackLinBase; p_proc->task.memmap.stack_lin_base = StackLinBase;
p_proc->task.memmap.stack_lin_limit = StackLinBase - 0x4000; //栈的界限将会一直动态变化目前赋值为16k这个值会根据esp的位置进行调整目前初始化为16K大小 p_proc->task.memmap.stack_lin_limit = StackLinBase - 0x4000; // 栈的界限将会一直动态变化目前赋值为16k这个值会根据esp的位置进行调整目前初始化为16K大小
p_proc->task.memmap.kernel_lin_base = KernelLinBase; p_proc->task.memmap.kernel_lin_base = KernelLinBase;
p_proc->task.memmap.kernel_lin_limit = KernelLinBase + KernelSize; //内核大小初始化为8M //add by visual 2016.5.10 p_proc->task.memmap.kernel_lin_limit = KernelLinBase + KernelSize; // 内核大小初始化为8M //add by visual 2016.5.10
/***************初始化PID进程页表*****************************/ /***************初始化PID进程页表*****************************/
if( 0 != init_page_pte(pid) ) if (0 != init_page_pte(pid))
{ {
disp_color_str("kernel_main Error:init_page_pte",0x74); disp_color_str("kernel_main Error:init_page_pte", 0x74);
return -1; return -1;
} }
// pde_addr_phy_temp = get_pde_phy_addr(pid);//获取该进程页目录物理地址 //delete by visual 2016.5.19 // pde_addr_phy_temp = get_pde_phy_addr(pid);//获取该进程页目录物理地址 //delete by visual 2016.5.19
/****************代码数据*****************************/ /****************代码数据*****************************/
p_proc->task.regs.eip= (u32)p_task->initial_eip;//进程入口线性地址 edit by visual 2016.5.4 p_proc->task.regs.eip = (u32)p_task->initial_eip; // 进程入口线性地址 edit by visual 2016.5.4
/****************栈(此时堆、栈已经区分,以后实验会重新规划堆的位置)*****************************/ /****************栈(此时堆、栈已经区分,以后实验会重新规划堆的位置)*****************************/
p_proc->task.regs.esp=(u32)StackLinBase; //栈地址最高处 p_proc->task.regs.esp = (u32)StackLinBase; // 栈地址最高处
for( AddrLin=StackLinBase ; AddrLin>p_proc->task.memmap.stack_lin_limit ; AddrLin-=num_4K ) for (AddrLin = StackLinBase; AddrLin > p_proc->task.memmap.stack_lin_limit; AddrLin -= num_4K)
{// { //
//addr_phy_temp = (u32)do_kmalloc_4k();//为栈申请一个物理页,Task的栈是在内核里面 //delete by visual 2016.5.19 // addr_phy_temp = (u32)do_kmalloc_4k();//为栈申请一个物理页,Task的栈是在内核里面 //delete by visual 2016.5.19
//if( addr_phy_temp<0 || (addr_phy_temp&0x3FF)!=0 ) // if( addr_phy_temp<0 || (addr_phy_temp&0x3FF)!=0 )
//{ //{
// disp_color_str("kernel_main Error:addr_phy_temp",0x74); // disp_color_str("kernel_main Error:addr_phy_temp",0x74);
// return -1; // return -1;
//} // }
err_temp = lin_mapping_phy( AddrLin,//线性地址 //add by visual 2016.5.9 err_temp = lin_mapping_phy(AddrLin, // 线性地址 //add by visual 2016.5.9
MAX_UNSIGNED_INT,//物理地址 //edit by visual 2016.5.19 MAX_UNSIGNED_INT, // 物理地址 //edit by visual 2016.5.19
pid,//进程pid //edit by visual 2016.5.19 pid, // 进程pid //edit by visual 2016.5.19
PG_P | PG_USU | PG_RWW,//页目录的属性位 PG_P | PG_USU | PG_RWW, // 页目录的属性位
PG_P | PG_USU | PG_RWW);//页表的属性位 PG_P | PG_USU | PG_RWW); // 页表的属性位
if( err_temp!=0 ) if (err_temp != 0)
{ {
disp_color_str("kernel_main Error:lin_mapping_phy",0x74); disp_color_str("kernel_main Error:lin_mapping_phy", 0x74);
return -1; return -1;
} }
} }
/***************copy registers data to kernel stack****************************/ /***************copy registers data to kernel stack****************************/
//copy registers data to the bottom of the new kernel stack // copy registers data to the bottom of the new kernel stack
//added by xw, 17/12/11 // added by xw, 17/12/11
p_regs = (char*)(p_proc + 1); p_regs = (char *)(p_proc + 1);
p_regs -= P_STACKTOP; p_regs -= P_STACKTOP;
memcpy(p_regs, (char*)p_proc, 18 * 4); memcpy(p_regs, (char *)p_proc, 18 * 4);
/***************some field about process switch****************************/ /***************some field about process switch****************************/
p_proc->task.esp_save_int = p_regs; //initialize esp_save_int, added by xw, 17/12/11 p_proc->task.esp_save_int = p_regs; // initialize esp_save_int, added by xw, 17/12/11
//p_proc->task.save_type = 1; // p_proc->task.save_type = 1;
p_proc->task.esp_save_context = p_regs - 10 * 4; //when the process is chosen to run for the first time, p_proc->task.esp_save_context = p_regs - 10 * 4; // when the process is chosen to run for the first time,
//sched() will fetch value from esp_save_context // sched() will fetch value from esp_save_context
eip_context = restart_restore; eip_context = restart_restore;
*(u32*)(p_regs - 4) = (u32)eip_context; //initialize EIP in the context, so the process can *(u32 *)(p_regs - 4) = (u32)eip_context; // initialize EIP in the context, so the process can
//start run. added by xw, 18/4/18 // start run. added by xw, 18/4/18
*(u32*)(p_regs - 8) = 0x1202; //initialize EFLAGS in the context, IF=1, IOPL=1. xw, 18/4/20 *(u32 *)(p_regs - 8) = 0x1202; // initialize EFLAGS in the context, IF=1, IOPL=1. xw, 18/4/20
/***************变量调整****************************/ /***************变量调整****************************/
p_proc++; p_proc++;
p_task++; p_task++;
selector_ldt += 1 << 3; selector_ldt += 1 << 3;
} }
for( ; pid<NR_K_PCBS ; pid++ ) for (; pid < NR_K_PCBS; pid++)
{//2>对中NR_TASKS~NR_K_PCBS的PCB表初始化,状态为IDLE,没有初始化esp(并没有生成,所以没有代码入口,只是留位置) { // 2>对中NR_TASKS~NR_K_PCBS的PCB表初始化,状态为IDLE,没有初始化esp(并没有生成,所以没有代码入口,只是留位置)
/*************基本信息*********************************/ /*************基本信息*********************************/
strcpy(p_proc->task.p_name, "Task"); //名称 strcpy(p_proc->task.p_name, "Task"); // 名称
p_proc->task.pid = pid; //pid p_proc->task.pid = pid; // pid
p_proc->task.stat = IDLE; //状态 p_proc->task.stat = IDLE; // 状态
/**************LDT*********************************/ /**************LDT*********************************/
p_proc->task.ldt_sel = selector_ldt; p_proc->task.ldt_sel = selector_ldt;
memcpy(&p_proc->task.ldts[0], &gdt[SELECTOR_KERNEL_CS >> 3],sizeof(DESCRIPTOR)); memcpy(&p_proc->task.ldts[0], &gdt[SELECTOR_KERNEL_CS >> 3], sizeof(DESCRIPTOR));
p_proc->task.ldts[0].attr1 = DA_C | PRIVILEGE_TASK << 5; p_proc->task.ldts[0].attr1 = DA_C | PRIVILEGE_TASK << 5;
memcpy(&p_proc->task.ldts[1], &gdt[SELECTOR_KERNEL_DS >> 3],sizeof(DESCRIPTOR)); memcpy(&p_proc->task.ldts[1], &gdt[SELECTOR_KERNEL_DS >> 3], sizeof(DESCRIPTOR));
p_proc->task.ldts[1].attr1 = DA_DRW | PRIVILEGE_TASK << 5; p_proc->task.ldts[1].attr1 = DA_DRW | PRIVILEGE_TASK << 5;
/**************寄存器初值**********************************/ /**************寄存器初值**********************************/
p_proc->task.regs.cs = ((8 * 0) & SA_RPL_MASK & SA_TI_MASK)| SA_TIL | RPL_TASK; p_proc->task.regs.cs = ((8 * 0) & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_TASK;
p_proc->task.regs.ds = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK)| SA_TIL | RPL_TASK; p_proc->task.regs.ds = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_TASK;
p_proc->task.regs.es = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK)| SA_TIL | RPL_TASK; p_proc->task.regs.es = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_TASK;
p_proc->task.regs.fs = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK)| SA_TIL | RPL_TASK; p_proc->task.regs.fs = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_TASK;
p_proc->task.regs.ss = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK)| SA_TIL | RPL_TASK; p_proc->task.regs.ss = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_TASK;
p_proc->task.regs.gs = (SELECTOR_KERNEL_GS & SA_RPL_MASK)| RPL_TASK; p_proc->task.regs.gs = (SELECTOR_KERNEL_GS & SA_RPL_MASK) | RPL_TASK;
p_proc->task.regs.eflags = 0x1202; /* IF=1, IOPL=1 */ p_proc->task.regs.eflags = 0x1202; /* IF=1, IOPL=1 */
/****************页表、代码数据、堆栈*****************************/ /****************页表、代码数据、堆栈*****************************/
// //
/***************copy registers data to kernel stack****************************/ /***************copy registers data to kernel stack****************************/
//copy registers data to the bottom of the new kernel stack // copy registers data to the bottom of the new kernel stack
//added by xw, 17/12/11 // added by xw, 17/12/11
p_regs = (char*)(p_proc + 1); p_regs = (char *)(p_proc + 1);
p_regs -= P_STACKTOP; p_regs -= P_STACKTOP;
memcpy(p_regs, (char*)p_proc, 18 * 4); memcpy(p_regs, (char *)p_proc, 18 * 4);
/***************some field about process switch****************************/ /***************some field about process switch****************************/
p_proc->task.esp_save_int = p_regs; //initialize esp_save_int, added by xw, 17/12/11 p_proc->task.esp_save_int = p_regs; // initialize esp_save_int, added by xw, 17/12/11
//p_proc->task.save_type = 1; // p_proc->task.save_type = 1;
p_proc->task.esp_save_context = p_regs - 10 * 4; //when the process is chosen to run for the first time, p_proc->task.esp_save_context = p_regs - 10 * 4; // when the process is chosen to run for the first time,
//sched() will fetch value from esp_save_context // sched() will fetch value from esp_save_context
eip_context = restart_restore; eip_context = restart_restore;
*(u32*)(p_regs - 4) = (u32)eip_context; //initialize EIP in the context, so the process can *(u32 *)(p_regs - 4) = (u32)eip_context; // initialize EIP in the context, so the process can
//start run. added by xw, 18/4/18 // start run. added by xw, 18/4/18
*(u32*)(p_regs - 8) = 0x1202; //initialize EFLAGS in the context, IF=1, IOPL=1. xw, 18/4/20 *(u32 *)(p_regs - 8) = 0x1202; // initialize EFLAGS in the context, IF=1, IOPL=1. xw, 18/4/20
/***************变量调整****************************/ /***************变量调整****************************/
p_proc++; p_proc++;
selector_ldt += 1 << 3; selector_ldt += 1 << 3;
} }
for( ; pid<NR_K_PCBS+1 ; pid++ ) for (; pid < NR_K_PCBS + 1; pid++)
{//initial 进程的初始化 //add by visual 2016.5.17 { // initial 进程的初始化 //add by visual 2016.5.17
/*************基本信息*********************************/ /*************基本信息*********************************/
strcpy(p_proc->task.p_name,"initial"); //名称 strcpy(p_proc->task.p_name, "initial"); // 名称
p_proc->task.pid = pid; //pid p_proc->task.pid = pid; // pid
p_proc->task.stat = READY; //状态 p_proc->task.stat = READY; // 状态
/**************LDT*********************************/ /**************LDT*********************************/
p_proc->task.ldt_sel = selector_ldt; p_proc->task.ldt_sel = selector_ldt;
memcpy(&p_proc->task.ldts[0], &gdt[SELECTOR_KERNEL_CS >> 3],sizeof(DESCRIPTOR)); memcpy(&p_proc->task.ldts[0], &gdt[SELECTOR_KERNEL_CS >> 3], sizeof(DESCRIPTOR));
p_proc->task.ldts[0].attr1 = DA_C | PRIVILEGE_TASK << 5; p_proc->task.ldts[0].attr1 = DA_C | PRIVILEGE_TASK << 5;
memcpy(&p_proc->task.ldts[1], &gdt[SELECTOR_KERNEL_DS >> 3],sizeof(DESCRIPTOR)); memcpy(&p_proc->task.ldts[1], &gdt[SELECTOR_KERNEL_DS >> 3], sizeof(DESCRIPTOR));
p_proc->task.ldts[1].attr1 = DA_DRW | PRIVILEGE_TASK << 5; p_proc->task.ldts[1].attr1 = DA_DRW | PRIVILEGE_TASK << 5;
/**************寄存器初值**********************************/ /**************寄存器初值**********************************/
p_proc->task.regs.cs = ((8 * 0) & SA_RPL_MASK & SA_TI_MASK)| SA_TIL | RPL_TASK; p_proc->task.regs.cs = ((8 * 0) & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_TASK;
p_proc->task.regs.ds = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK)| SA_TIL | RPL_TASK; p_proc->task.regs.ds = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_TASK;
p_proc->task.regs.es = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK)| SA_TIL | RPL_TASK; p_proc->task.regs.es = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_TASK;
p_proc->task.regs.fs = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK)| SA_TIL | RPL_TASK; p_proc->task.regs.fs = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_TASK;
p_proc->task.regs.ss = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK)| SA_TIL | RPL_TASK; p_proc->task.regs.ss = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_TASK;
p_proc->task.regs.gs = (SELECTOR_KERNEL_GS & SA_RPL_MASK)| RPL_TASK; p_proc->task.regs.gs = (SELECTOR_KERNEL_GS & SA_RPL_MASK) | RPL_TASK;
p_proc->task.regs.eflags = 0x1202; /* IF=1, IOPL=1 */ p_proc->task.regs.eflags = 0x1202; /* IF=1, IOPL=1 */
//p_proc->task.cr3 在页表初始化中处理 // p_proc->task.cr3 在页表初始化中处理
/**************线性地址布局初始化**********************************/ // edit by visual 2016.5.25
/**************线性地址布局初始化**********************************/ //edit by visual 2016.5.25 p_proc->task.memmap.text_lin_base = 0; // initial这些段的数据并不清楚在变身init的时候才在中赋新值
p_proc->task.memmap.text_lin_base = 0; //initial这些段的数据并不清楚在变身init的时候才在中赋新值 p_proc->task.memmap.text_lin_limit = 0; // initial这些段的数据并不清楚在变身init的时候才在exec中赋新值
p_proc->task.memmap.text_lin_limit = 0; //initial这些段的数据并不清楚在变身init的时候才在exec中赋新值 p_proc->task.memmap.data_lin_base = 0; // initial这些段的数据并不清楚在变身init的时候才在exec中赋新值
p_proc->task.memmap.data_lin_base = 0; //initial这些段的数据并不清楚在变身init的时候才在exec中赋新值 p_proc->task.memmap.data_lin_limit = 0; // initial这些段的数据并不清楚在变身init的时候才在exec中赋新值
p_proc->task.memmap.data_lin_limit= 0; //initial这些段的数据并不清楚在变身init的时候才在exec中赋新值 p_proc->task.memmap.vpage_lin_base = VpageLinBase; // 保留内存基址
p_proc->task.memmap.vpage_lin_base = VpageLinBase; //保留内存基址 p_proc->task.memmap.vpage_lin_limit = VpageLinBase; // 保留内存界限
p_proc->task.memmap.vpage_lin_limit = VpageLinBase; //保留内存界限 p_proc->task.memmap.heap_lin_base = HeapLinBase; // 堆基址
p_proc->task.memmap.heap_lin_base = HeapLinBase; //堆基址 p_proc->task.memmap.heap_lin_limit = HeapLinBase; // 堆界限
p_proc->task.memmap.heap_lin_limit = HeapLinBase; //堆界限 p_proc->task.memmap.stack_lin_base = StackLinBase; // 栈基址
p_proc->task.memmap.stack_lin_base = StackLinBase; //栈基址 p_proc->task.memmap.stack_lin_limit = StackLinBase - 0x4000; // 栈界限(使用时注意栈的生长方向)
p_proc->task.memmap.stack_lin_limit = StackLinBase - 0x4000; //栈界限(使用时注意栈的生长方向) p_proc->task.memmap.arg_lin_base = ArgLinBase; // 参数内存基址
p_proc->task.memmap.arg_lin_base = ArgLinBase; //参数内存基址 p_proc->task.memmap.arg_lin_limit = ArgLinBase; // 参数内存界限
p_proc->task.memmap.arg_lin_limit = ArgLinBase; //参数内存界限 p_proc->task.memmap.kernel_lin_base = KernelLinBase; // 内核基址
p_proc->task.memmap.kernel_lin_base = KernelLinBase; //内核基址 p_proc->task.memmap.kernel_lin_limit = KernelLinBase + KernelSize; // 内核大小初始化为8M
p_proc->task.memmap.kernel_lin_limit = KernelLinBase + KernelSize; //内核大小初始化为8M
/*************************进程树信息初始化***************************************/ /*************************进程树信息初始化***************************************/
p_proc->task.info.type = TYPE_PROCESS; //当前是进程还是线程 p_proc->task.info.type = TYPE_PROCESS; // 当前是进程还是线程
p_proc->task.info.real_ppid = -1; //亲父进程,创建它的那个进程 p_proc->task.info.real_ppid = -1; // 亲父进程,创建它的那个进程
p_proc->task.info.ppid = -1; //当前父进程 p_proc->task.info.ppid = -1; // 当前父进程
p_proc->task.info.child_p_num = 0; //子进程数量 p_proc->task.info.child_p_num = 0; // 子进程数量
//p_proc->task.info.child_process[NR_CHILD_MAX];//子进程列表 // p_proc->task.info.child_process[NR_CHILD_MAX];//子进程列表
p_proc->task.info.child_t_num = 0; //子线程数量 p_proc->task.info.child_t_num = 0; // 子线程数量
//p_proc->task.info.child_thread[NR_CHILD_MAX];//子线程列表 // p_proc->task.info.child_thread[NR_CHILD_MAX];//子线程列表
p_proc->task.info.text_hold = 1; //是否拥有代码 p_proc->task.info.text_hold = 1; // 是否拥有代码
p_proc->task.info.data_hold = 1; //是否拥有数据 p_proc->task.info.data_hold = 1; // 是否拥有数据
/***************初始化PID进程页表*****************************/ /***************初始化PID进程页表*****************************/
if( 0 != init_page_pte(pid) ) if (0 != init_page_pte(pid))
{ {
disp_color_str("kernel_main Error:init_page_pte",0x74); disp_color_str("kernel_main Error:init_page_pte", 0x74);
return -1; return -1;
} }
//pde_addr_phy_temp = get_pde_phy_addr(pid);//获取该进程页目录物理地址 //edit by visual 2016.5.19 // pde_addr_phy_temp = get_pde_phy_addr(pid);//获取该进程页目录物理地址 //edit by visual 2016.5.19
/****************代码数据*****************************/ /****************代码数据*****************************/
p_proc->task.regs.eip= (u32)initial;//进程入口线性地址 edit by visual 2016.5.17 p_proc->task.regs.eip = (u32)initial; // 进程入口线性地址 edit by visual 2016.5.17
/****************栈(此时堆、栈已经区分,以后实验会重新规划堆的位置)*****************************/ /****************栈(此时堆、栈已经区分,以后实验会重新规划堆的位置)*****************************/
p_proc->task.regs.esp=(u32)StackLinBase; //栈地址最高处 p_proc->task.regs.esp = (u32)StackLinBase; // 栈地址最高处
for( AddrLin=StackLinBase ; AddrLin>p_proc->task.memmap.stack_lin_limit ; AddrLin-=num_4K ) for (AddrLin = StackLinBase; AddrLin > p_proc->task.memmap.stack_lin_limit; AddrLin -= num_4K)
{// { //
//addr_phy_temp = (u32)do_kmalloc_4k();//为栈申请一个物理页,Task的栈是在内核里面 //delete by visual 2016.5.19 // addr_phy_temp = (u32)do_kmalloc_4k();//为栈申请一个物理页,Task的栈是在内核里面 //delete by visual 2016.5.19
//if( addr_phy_temp<0 || (addr_phy_temp&0x3FF)!=0 ) // if( addr_phy_temp<0 || (addr_phy_temp&0x3FF)!=0 )
//{ //{
// disp_color_str("kernel_main Error:addr_phy_temp",0x74); // disp_color_str("kernel_main Error:addr_phy_temp",0x74);
// return -1; // return -1;
//} // }
err_temp = lin_mapping_phy( AddrLin,//线性地址 err_temp = lin_mapping_phy(AddrLin, // 线性地址
MAX_UNSIGNED_INT,//物理地址 //edit by visual 2016.5.19 MAX_UNSIGNED_INT, // 物理地址 //edit by visual 2016.5.19
pid,//进程pid //edit by visual 2016.5.19 pid, // 进程pid //edit by visual 2016.5.19
PG_P | PG_USU | PG_RWW,//页目录的属性位 PG_P | PG_USU | PG_RWW, // 页目录的属性位
PG_P | PG_USU | PG_RWW);//页表的属性位 PG_P | PG_USU | PG_RWW); // 页表的属性位
if( err_temp!=0 ) if (err_temp != 0)
{ {
disp_color_str("kernel_main Error:lin_mapping_phy",0x74); disp_color_str("kernel_main Error:lin_mapping_phy", 0x74);
return -1; return -1;
} }
} }
/***************copy registers data to kernel stack****************************/ /***************copy registers data to kernel stack****************************/
//copy registers data to the bottom of the new kernel stack // copy registers data to the bottom of the new kernel stack
//added by xw, 17/12/11 // added by xw, 17/12/11
p_regs = (char*)(p_proc + 1); p_regs = (char *)(p_proc + 1);
p_regs -= P_STACKTOP; p_regs -= P_STACKTOP;
memcpy(p_regs, (char*)p_proc, 18 * 4); memcpy(p_regs, (char *)p_proc, 18 * 4);
/***************some field about process switch****************************/ /***************some field about process switch****************************/
p_proc->task.esp_save_int = p_regs; //initialize esp_save_int, added by xw, 17/12/11 p_proc->task.esp_save_int = p_regs; // initialize esp_save_int, added by xw, 17/12/11
//p_proc->task.save_type = 1; // p_proc->task.save_type = 1;
p_proc->task.esp_save_context = p_regs - 10 * 4; //when the process is chosen to run for the first time, p_proc->task.esp_save_context = p_regs - 10 * 4; // when the process is chosen to run for the first time,
//sched() will fetch value from esp_save_context // sched() will fetch value from esp_save_context
eip_context = restart_restore; eip_context = restart_restore;
*(u32*)(p_regs - 4) = (u32)eip_context; //initialize EIP in the context, so the process can *(u32 *)(p_regs - 4) = (u32)eip_context; // initialize EIP in the context, so the process can
//start run. added by xw, 18/4/18 // start run. added by xw, 18/4/18
*(u32*)(p_regs - 8) = 0x1202; //initialize EFLAGS in the context, IF=1, IOPL=1. xw, 18/4/20 *(u32 *)(p_regs - 8) = 0x1202; // initialize EFLAGS in the context, IF=1, IOPL=1. xw, 18/4/20
/***************变量调整****************************/ /***************变量调整****************************/
p_proc++; p_proc++;
selector_ldt += 1 << 3; selector_ldt += 1 << 3;
} }
for( ; pid<NR_PCBS ; pid++ ) for (; pid < NR_PCBS; pid++)
{//3>对后NR_K_PCBS~NR_PCBS的PCB表部分初始化,(名称,pid,stat,LDT选择子),状态为IDLE. { // 3>对后NR_K_PCBS~NR_PCBS的PCB表部分初始化,(名称,pid,stat,LDT选择子),状态为IDLE.
/*************基本信息*********************************/ /*************基本信息*********************************/
strcpy(p_proc->task.p_name, "USER"); //名称 strcpy(p_proc->task.p_name, "USER"); // 名称
p_proc->task.pid = pid; //pid p_proc->task.pid = pid; // pid
p_proc->task.stat = IDLE; //状态 p_proc->task.stat = IDLE; // 状态
/**************LDT*********************************/ /**************LDT*********************************/
p_proc->task.ldt_sel = selector_ldt; p_proc->task.ldt_sel = selector_ldt;
memcpy(&p_proc->task.ldts[0], &gdt[SELECTOR_KERNEL_CS >> 3],sizeof(DESCRIPTOR)); memcpy(&p_proc->task.ldts[0], &gdt[SELECTOR_KERNEL_CS >> 3], sizeof(DESCRIPTOR));
p_proc->task.ldts[0].attr1 = DA_C | PRIVILEGE_USER << 5; p_proc->task.ldts[0].attr1 = DA_C | PRIVILEGE_USER << 5;
memcpy(&p_proc->task.ldts[1], &gdt[SELECTOR_KERNEL_DS >> 3],sizeof(DESCRIPTOR)); memcpy(&p_proc->task.ldts[1], &gdt[SELECTOR_KERNEL_DS >> 3], sizeof(DESCRIPTOR));
p_proc->task.ldts[1].attr1 = DA_DRW | PRIVILEGE_USER << 5; p_proc->task.ldts[1].attr1 = DA_DRW | PRIVILEGE_USER << 5;
/**************寄存器初值**********************************/ /**************寄存器初值**********************************/
p_proc->task.regs.cs = ((8 * 0) & SA_RPL_MASK & SA_TI_MASK)| SA_TIL | RPL_USER; p_proc->task.regs.cs = ((8 * 0) & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_USER;
p_proc->task.regs.ds = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK)| SA_TIL | RPL_USER; p_proc->task.regs.ds = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_USER;
p_proc->task.regs.es = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK)| SA_TIL | RPL_USER; p_proc->task.regs.es = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_USER;
p_proc->task.regs.fs = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK)| SA_TIL | RPL_USER; p_proc->task.regs.fs = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_USER;
p_proc->task.regs.ss = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK)| SA_TIL | RPL_USER; p_proc->task.regs.ss = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_USER;
p_proc->task.regs.gs = (SELECTOR_KERNEL_GS & SA_RPL_MASK)| RPL_USER; p_proc->task.regs.gs = (SELECTOR_KERNEL_GS & SA_RPL_MASK) | RPL_USER;
p_proc->task.regs.eflags = 0x0202; /* IF=1, 倒数第二位恒为1 */ p_proc->task.regs.eflags = 0x0202; /* IF=1, 倒数第二位恒为1 */
/****************页表、代码数据、堆栈*****************************/ /****************页表、代码数据、堆栈*****************************/
// //
/***************copy registers data to kernel stack****************************/ /***************copy registers data to kernel stack****************************/
//copy registers data to the bottom of the new kernel stack // copy registers data to the bottom of the new kernel stack
//added by xw, 17/12/11 // added by xw, 17/12/11
p_regs = (char*)(p_proc + 1); p_regs = (char *)(p_proc + 1);
p_regs -= P_STACKTOP; p_regs -= P_STACKTOP;
memcpy(p_regs, (char*)p_proc, 18 * 4); memcpy(p_regs, (char *)p_proc, 18 * 4);
/***************some field about process switch****************************/ /***************some field about process switch****************************/
p_proc->task.esp_save_int = p_regs; //initialize esp_save_int, added by xw, 17/12/11 p_proc->task.esp_save_int = p_regs; // initialize esp_save_int, added by xw, 17/12/11
//p_proc->task.save_type = 1; // p_proc->task.save_type = 1;
p_proc->task.esp_save_context = p_regs - 10 * 4; //when the process is chosen to run for the first time, p_proc->task.esp_save_context = p_regs - 10 * 4; // when the process is chosen to run for the first time,
//sched() will fetch value from esp_save_context // sched() will fetch value from esp_save_context
eip_context = restart_restore; eip_context = restart_restore;
*(u32*)(p_regs - 4) = (u32)eip_context; //initialize EIP in the context, so the process can *(u32 *)(p_regs - 4) = (u32)eip_context; // initialize EIP in the context, so the process can
//start run. added by xw, 18/4/18 // start run. added by xw, 18/4/18
*(u32*)(p_regs - 8) = 0x1202; //initialize EFLAGS in the context, IF=1, IOPL=1. xw, 18/4/20 *(u32 *)(p_regs - 8) = 0x1202; // initialize EFLAGS in the context, IF=1, IOPL=1. xw, 18/4/20
/***************变量调整****************************/ /***************变量调整****************************/
p_proc++; p_proc++;
@ -460,7 +457,7 @@ static int initialize_processes()
proc_table[0].task.ticks = proc_table[0].task.priority = 1; proc_table[0].task.ticks = proc_table[0].task.priority = 1;
proc_table[1].task.ticks = proc_table[1].task.priority = 1; proc_table[1].task.ticks = proc_table[1].task.priority = 1;
proc_table[2].task.ticks = proc_table[2].task.priority = 1; proc_table[2].task.ticks = proc_table[2].task.priority = 1;
proc_table[3].task.ticks = proc_table[3].task.priority = 1; //added by xw, 18/8/27 proc_table[3].task.ticks = proc_table[3].task.priority = 1; // added by xw, 18/8/27
proc_table[NR_K_PCBS].task.ticks = proc_table[NR_K_PCBS].task.priority = 1; proc_table[NR_K_PCBS].task.ticks = proc_table[NR_K_PCBS].task.priority = 1;
/* When the first process begin running, a clock-interruption will happen immediately. /* When the first process begin running, a clock-interruption will happen immediately.

View File

@ -13,7 +13,7 @@
#include "stdio.h" #include "stdio.h"
int current_console; //当前显示在屏幕上的console int current_console; // 当前显示在屏幕上的console
void tty_write(TTY *tty, char *buf, int len); void tty_write(TTY *tty, char *buf, int len);
int tty_read(TTY *tty, char *buf, int len); int tty_read(TTY *tty, char *buf, int len);
@ -30,9 +30,11 @@ int cur_ntty = 0;
static keyboard_buf keyboardbuf[3]; static keyboard_buf keyboardbuf[3];
static vga_buf vgabuf[3]; static vga_buf vgabuf[3];
void init_tty_main() { void init_tty_main()
NTTY* tty; {
for (int i = 0; i < 3; ++ i) { NTTY *tty;
for (int i = 0; i < 3; ++i)
{
tty = &ntty_table[i]; tty = &ntty_table[i];
tty->driver_type = 1; // vga tty->driver_type = 1; // vga
// tty->input_buf = (void*)do_kmalloc(sizeof(keyboard_buf)); // tty->input_buf = (void*)do_kmalloc(sizeof(keyboard_buf));
@ -115,17 +117,17 @@ void in_process(TTY *p_tty, u32 key)
void task_tty() void task_tty()
{ {
#ifdef DEBUGNEW #ifdef DEBUGNEW
// NTTY* p_tty; // NTTY* p_tty;
// for (p_tty = ntty_table; p_tty < ntty_table + 3; ++ p_tty) { // for (p_tty = ntty_table; p_tty < ntty_table + 3; ++ p_tty) {
// init_ntty(p_tty); // init_ntty(p_tty);
// } // }
while(1) while (1)
{ {
vga_tty_flush(&ntty_table[cur_ntty]); vga_tty_flush(&ntty_table[cur_ntty]);
} }
#else #else
TTY *p_tty; TTY *p_tty;
for (p_tty = TTY_FIRST; p_tty < TTY_END; p_tty++) for (p_tty = TTY_FIRST; p_tty < TTY_END; p_tty++)
{ {
@ -135,7 +137,7 @@ void task_tty()
select_console(0); select_console(0);
//设置第一个tty光标位置第一个tty需要特殊处理 // 设置第一个tty光标位置第一个tty需要特殊处理
disable_int(); disable_int();
outb(CRTC_ADDR_REG, CURSOR_H); outb(CRTC_ADDR_REG, CURSOR_H);
outb(CRTC_DATA_REG, ((disp_pos / 2) >> 8) & 0xFF); outb(CRTC_DATA_REG, ((disp_pos / 2) >> 8) & 0xFF);
@ -143,7 +145,7 @@ void task_tty()
outb(CRTC_DATA_REG, (disp_pos / 2) & 0xFF); outb(CRTC_DATA_REG, (disp_pos / 2) & 0xFF);
enable_int(); enable_int();
//轮询 // 轮询
while (1) while (1)
{ {
for (p_tty = TTY_FIRST; p_tty < TTY_END; p_tty++) for (p_tty = TTY_FIRST; p_tty < TTY_END; p_tty++)
@ -157,7 +159,7 @@ void task_tty()
} while (p_tty->ibuf_cnt); } while (p_tty->ibuf_cnt);
} }
} }
#endif #endif
} }
static void init_tty(TTY *p_tty) static void init_tty(TTY *p_tty)
@ -184,7 +186,7 @@ static void tty_mouse(TTY *tty)
{ {
if (tty->mouse_Y > MOUSE_UPDOWN_BOUND) if (tty->mouse_Y > MOUSE_UPDOWN_BOUND)
{ //按住鼠标左键向上滚动 { // 按住鼠标左键向上滚动
if (tty->console->current_line < 43) if (tty->console->current_line < 43)
{ {
disable_int(); disable_int();
@ -198,7 +200,7 @@ static void tty_mouse(TTY *tty)
} }
} }
else if (tty->mouse_Y < -MOUSE_UPDOWN_BOUND) else if (tty->mouse_Y < -MOUSE_UPDOWN_BOUND)
{ //按住鼠标左键向下滚动 { // 按住鼠标左键向下滚动
if (tty->console->current_line > 0) if (tty->console->current_line > 0)
{ {
disable_int(); disable_int();
@ -214,7 +216,7 @@ static void tty_mouse(TTY *tty)
} }
if (tty->mouse_mid_button) if (tty->mouse_mid_button)
{ //点击中键复原 { // 点击中键复原
disable_int(); disable_int();
tty->console->current_line = 0; tty->console->current_line = 0;
outb(CRTC_ADDR_REG, START_ADDR_H); outb(CRTC_ADDR_REG, START_ADDR_H);
@ -299,7 +301,8 @@ static void put_key(TTY *tty, u32 key)
void tty_write(TTY *tty, char *buf, int len) void tty_write(TTY *tty, char *buf, int len)
{ {
#ifdef DEBUGNEW #ifdef DEBUGNEW
while (--len >= 0) { while (--len >= 0)
{
vga_tty_write(&ntty_table[cur_ntty], *buf++); vga_tty_write(&ntty_table[cur_ntty], *buf++);
} }
// vga_tty_flush(&ntty_table[cur_ntty]); // vga_tty_flush(&ntty_table[cur_ntty]);

View File

@ -1,6 +1,6 @@
/********************************************************** /**********************************************************
* vfs.c //added by mingxuan 2019-5-17 * vfs.c //added by mingxuan 2019-5-17
***********************************************************/ ***********************************************************/
#include "type.h" #include "type.h"
#include "const.h" #include "const.h"
@ -17,21 +17,21 @@
#include "fat32.h" #include "fat32.h"
#include "stdio.h" #include "stdio.h"
//static struct device device_table[NR_DEV]; //deleted by mingxuan 2020-10-18 // static struct device device_table[NR_DEV]; //deleted by mingxuan 2020-10-18
static struct vfs vfs_table[NR_FS]; //modified by mingxuan 2020-10-18 static struct vfs vfs_table[NR_FS]; // modified by mingxuan 2020-10-18
struct file_desc f_desc_table[NR_FILE_DESC]; struct file_desc f_desc_table[NR_FILE_DESC];
struct super_block super_block[NR_SUPER_BLOCK]; //added by mingxuan 2020-10-30 struct super_block super_block[NR_SUPER_BLOCK]; // added by mingxuan 2020-10-30
//static struct file_op f_op_table[NR_fs]; //文件系统操作表 // static struct file_op f_op_table[NR_fs]; //文件系统操作表
static struct file_op f_op_table[NR_FS_OP]; //modified by mingxuan 2020-10-18 static struct file_op f_op_table[NR_FS_OP]; // modified by mingxuan 2020-10-18
static struct sb_op sb_op_table[NR_SB_OP]; //added by mingxuan 2020-10-30 static struct sb_op sb_op_table[NR_SB_OP]; // added by mingxuan 2020-10-30
//static void init_dev_table();//deleted by mingxuan 2020-10-30 // static void init_dev_table();//deleted by mingxuan 2020-10-30
static void init_vfs_table(); //modified by mingxuan 2020-10-30 static void init_vfs_table(); // modified by mingxuan 2020-10-30
void init_file_desc_table(); //added by mingxuan 2020-10-30 void init_file_desc_table(); // added by mingxuan 2020-10-30
void init_fileop_table(); void init_fileop_table();
void init_super_block_table(); //added by mingxuan 2020-10-30 void init_super_block_table(); // added by mingxuan 2020-10-30
void init_sb_op_table(); void init_sb_op_table();
static int get_index(char path[]); static int get_index(char path[]);
@ -43,13 +43,13 @@ void init_vfs()
init_fileop_table(); init_fileop_table();
init_super_block_table(); init_super_block_table();
init_sb_op_table(); //added by mingxuan 2020-10-30 init_sb_op_table(); // added by mingxuan 2020-10-30
//init_dev_table(); //deleted by mingxuan 2020-10-30 // init_dev_table(); //deleted by mingxuan 2020-10-30
init_vfs_table(); //modified by mingxuan 2020-10-30 init_vfs_table(); // modified by mingxuan 2020-10-30
} }
//added by mingxuan 2020-10-30 // added by mingxuan 2020-10-30
void init_file_desc_table() void init_file_desc_table()
{ {
int i; int i;
@ -85,130 +85,136 @@ void init_fileop_table()
f_op_table[2].opendir = OpenDir; f_op_table[2].opendir = OpenDir;
f_op_table[2].createdir = CreateDir; f_op_table[2].createdir = CreateDir;
f_op_table[2].deletedir = DeleteDir; f_op_table[2].deletedir = DeleteDir;
} }
//added by mingxuan 2020-10-30 // added by mingxuan 2020-10-30
void init_super_block_table(){ void init_super_block_table()
struct super_block * sb = super_block; //deleted by mingxuan 2020-10-30 {
struct super_block *sb = super_block; // deleted by mingxuan 2020-10-30
//super_block[0] is tty0, super_block[1] is tty1, uper_block[2] is tty2 // super_block[0] is tty0, super_block[1] is tty1, uper_block[2] is tty2
for(; sb < &super_block[3]; sb++) { for (; sb < &super_block[3]; sb++)
{
sb->sb_dev = DEV_CHAR_TTY; sb->sb_dev = DEV_CHAR_TTY;
sb->fs_type = TTY_FS_TYPE; sb->fs_type = TTY_FS_TYPE;
} }
//super_block[3] is orange's superblock // super_block[3] is orange's superblock
sb->sb_dev = DEV_HD; sb->sb_dev = DEV_HD;
sb->fs_type = ORANGE_TYPE; sb->fs_type = ORANGE_TYPE;
sb++; sb++;
//super_block[4] is fat32's superblock // super_block[4] is fat32's superblock
sb->sb_dev = DEV_HD; sb->sb_dev = DEV_HD;
sb->fs_type = FAT32_TYPE; sb->fs_type = FAT32_TYPE;
sb++; sb++;
//another super_block are free // another super_block are free
for (; sb < &super_block[NR_SUPER_BLOCK]; sb++) { for (; sb < &super_block[NR_SUPER_BLOCK]; sb++)
{
sb->sb_dev = NO_DEV; sb->sb_dev = NO_DEV;
sb->fs_type = NO_FS_TYPE; sb->fs_type = NO_FS_TYPE;
} }
} }
//added by mingxuan 2020-10-30 // added by mingxuan 2020-10-30
void init_sb_op_table(){ void init_sb_op_table()
//orange {
// orange
sb_op_table[0].read_super_block = read_super_block; sb_op_table[0].read_super_block = read_super_block;
sb_op_table[0].get_super_block = get_super_block; sb_op_table[0].get_super_block = get_super_block;
//fat32 and tty // fat32 and tty
sb_op_table[1].read_super_block = NULL; sb_op_table[1].read_super_block = NULL;
sb_op_table[1].get_super_block = NULL; sb_op_table[1].get_super_block = NULL;
} }
//static void init_dev_table(){ // static void init_dev_table(){
static void init_vfs_table(){ // modified by mingxuan 2020-10-30 static void init_vfs_table()
{ // modified by mingxuan 2020-10-30
// 我们假设每个tty就是一个文件系统 // 我们假设每个tty就是一个文件系统
// tty0 // tty0
// device_table[0].dev_name="dev_tty0"; // device_table[0].dev_name="dev_tty0";
// device_table[0].op = &f_op_table[0]; // device_table[0].op = &f_op_table[0];
vfs_table[0].fs_name = "dev_tty0"; //modifed by mingxuan 2020-10-18 vfs_table[0].fs_name = "dev_tty0"; // modifed by mingxuan 2020-10-18
vfs_table[0].op = &f_op_table[0]; vfs_table[0].op = &f_op_table[0];
vfs_table[0].sb = &super_block[0]; //每个tty都有一个superblock //added by mingxuan 2020-10-30 vfs_table[0].sb = &super_block[0]; // 每个tty都有一个superblock //added by mingxuan 2020-10-30
vfs_table[0].s_op = &sb_op_table[1]; //added by mingxuan 2020-10-30 vfs_table[0].s_op = &sb_op_table[1]; // added by mingxuan 2020-10-30
// tty1 // tty1
//device_table[1].dev_name="dev_tty1"; // device_table[1].dev_name="dev_tty1";
//device_table[1].op =&f_op_table[0]; // device_table[1].op =&f_op_table[0];
vfs_table[1].fs_name = "dev_tty1"; //modifed by mingxuan 2020-10-18 vfs_table[1].fs_name = "dev_tty1"; // modifed by mingxuan 2020-10-18
vfs_table[1].op = &f_op_table[0]; vfs_table[1].op = &f_op_table[0];
vfs_table[1].sb = &super_block[1]; //每个tty都有一个superblock //added by mingxuan 2020-10-30 vfs_table[1].sb = &super_block[1]; // 每个tty都有一个superblock //added by mingxuan 2020-10-30
vfs_table[1].s_op = &sb_op_table[1]; //added by mingxuan 2020-10-30 vfs_table[1].s_op = &sb_op_table[1]; // added by mingxuan 2020-10-30
// tty2 // tty2
//device_table[2].dev_name="dev_tty2"; // device_table[2].dev_name="dev_tty2";
//device_table[2].op=&f_op_table[0]; // device_table[2].op=&f_op_table[0];
vfs_table[2].fs_name = "dev_tty2"; //modifed by mingxuan 2020-10-18 vfs_table[2].fs_name = "dev_tty2"; // modifed by mingxuan 2020-10-18
vfs_table[2].op = &f_op_table[0]; vfs_table[2].op = &f_op_table[0];
vfs_table[2].sb = &super_block[2]; //每个tty都有一个superblock //added by mingxuan 2020-10-30 vfs_table[2].sb = &super_block[2]; // 每个tty都有一个superblock //added by mingxuan 2020-10-30
vfs_table[2].s_op = &sb_op_table[1]; //added by mingxuan 2020-10-30 vfs_table[2].s_op = &sb_op_table[1]; // added by mingxuan 2020-10-30
// fat32 // fat32
//device_table[3].dev_name="fat0"; // device_table[3].dev_name="fat0";
//device_table[3].op=&f_op_table[2]; // device_table[3].op=&f_op_table[2];
vfs_table[3].fs_name = "fat0"; //modifed by mingxuan 2020-10-18 vfs_table[3].fs_name = "fat0"; // modifed by mingxuan 2020-10-18
vfs_table[3].op = &f_op_table[2]; vfs_table[3].op = &f_op_table[2];
vfs_table[3].sb = &super_block[4]; //added by mingxuan 2020-10-30 vfs_table[3].sb = &super_block[4]; // added by mingxuan 2020-10-30
vfs_table[3].s_op = &sb_op_table[1]; //added by mingxuan 2020-10-30 vfs_table[3].s_op = &sb_op_table[1]; // added by mingxuan 2020-10-30
// orange // orange
//device_table[4].dev_name="orange"; // device_table[4].dev_name="orange";
//device_table[4].op=&f_op_table[1]; // device_table[4].op=&f_op_table[1];
vfs_table[4].fs_name = "orange"; //modifed by mingxuan 2020-10-18 vfs_table[4].fs_name = "orange"; // modifed by mingxuan 2020-10-18
vfs_table[4].op = &f_op_table[1]; vfs_table[4].op = &f_op_table[1];
vfs_table[4].sb = &super_block[3]; //added by mingxuan 2020-10-30 vfs_table[4].sb = &super_block[3]; // added by mingxuan 2020-10-30
vfs_table[4].s_op = &sb_op_table[0]; //added by mingxuan 2020-10-30 vfs_table[4].s_op = &sb_op_table[0]; // added by mingxuan 2020-10-30
} }
static int get_index(char path[]){ static int get_index(char path[])
{
int pathlen = strlen(path); int pathlen = strlen(path);
//char dev_name[DEV_NAME_LEN]; // char dev_name[DEV_NAME_LEN];
char fs_name[DEV_NAME_LEN]; //modified by mingxuan 2020-10-18 char fs_name[DEV_NAME_LEN]; // modified by mingxuan 2020-10-18
int len = (pathlen < DEV_NAME_LEN) ? pathlen : DEV_NAME_LEN; int len = (pathlen < DEV_NAME_LEN) ? pathlen : DEV_NAME_LEN;
int i,a=0; int i, a = 0;
for(i=0;i<len;i++){ for (i = 0; i < len; i++)
if( path[i] == '/'){ {
a=i; if (path[i] == '/')
{
a = i;
a++; a++;
break; break;
} }
else { else
//dev_name[i] = path[i]; {
fs_name[i] = path[i]; //modified by mingxuan 2020-10-18 // dev_name[i] = path[i];
fs_name[i] = path[i]; // modified by mingxuan 2020-10-18
} }
} }
//dev_name[i] = '\0'; // dev_name[i] = '\0';
fs_name[i] = '\0'; //modified by mingxuan 2020-10-18 fs_name[i] = '\0'; // modified by mingxuan 2020-10-18
for(i=0;i<pathlen-a;i++) for (i = 0; i < pathlen - a; i++)
path[i] = path[i+a]; path[i] = path[i + a];
path[pathlen-a] = '\0'; path[pathlen - a] = '\0';
//for(i=0;i<NR_DEV;i++) // for(i=0;i<NR_DEV;i++)
for(i=0;i<NR_FS;i++) //modified by mingxuan 2020-10-29 for (i = 0; i < NR_FS; i++) // modified by mingxuan 2020-10-29
{ {
// if(!strcmp(dev_name, device_table[i].dev_name)) // if(!strcmp(dev_name, device_table[i].dev_name))
if(!strcmp(fs_name, vfs_table[i].fs_name)) //modified by mingxuan 2020-10-18 if (!strcmp(fs_name, vfs_table[i].fs_name)) // modified by mingxuan 2020-10-18
return i; return i;
} }
return -1; return -1;
} }
/*======================================================================* /*======================================================================*
sys_* sys_*
*======================================================================*/ *======================================================================*/
@ -238,92 +244,103 @@ int sys_lseek(void *uesp)
return do_vlseek(get_arg(uesp, 1), get_arg(uesp, 2), get_arg(uesp, 3)); return do_vlseek(get_arg(uesp, 1), get_arg(uesp, 2), get_arg(uesp, 3));
} }
int sys_unlink(void *uesp) { int sys_unlink(void *uesp)
{
return do_vunlink((const char *)get_arg(uesp, 1)); return do_vunlink((const char *)get_arg(uesp, 1));
} }
int sys_create(void *uesp) { int sys_create(void *uesp)
{
return do_vcreate((char *)get_arg(uesp, 1)); return do_vcreate((char *)get_arg(uesp, 1));
} }
int sys_delete(void *uesp) { int sys_delete(void *uesp)
{
return do_vdelete((char *)get_arg(uesp, 1)); return do_vdelete((char *)get_arg(uesp, 1));
} }
int sys_opendir(void *uesp) { int sys_opendir(void *uesp)
{
return do_vopendir((char *)get_arg(uesp, 1)); return do_vopendir((char *)get_arg(uesp, 1));
} }
int sys_createdir(void *uesp) { int sys_createdir(void *uesp)
{
return do_vcreatedir((char *)get_arg(uesp, 1)); return do_vcreatedir((char *)get_arg(uesp, 1));
} }
int sys_deletedir(void *uesp) { int sys_deletedir(void *uesp)
{
return do_vdeletedir((char *)get_arg(uesp, 1)); return do_vdeletedir((char *)get_arg(uesp, 1));
} }
/*======================================================================* /*======================================================================*
do_v* do_v*
*======================================================================*/ *======================================================================*/
int do_vopen(const char *path, int flags) { int do_vopen(const char *path, int flags)
{
int pathlen = strlen(path); int pathlen = strlen(path);
char pathname[MAX_PATH]; char pathname[MAX_PATH];
strcpy(pathname,(char *)path); strcpy(pathname, (char *)path);
pathname[pathlen] = 0; pathname[pathlen] = 0;
int index; int index;
int fd = -1; int fd = -1;
index = get_index(pathname); index = get_index(pathname);
if(index == -1){ if (index == -1)
{
kprintf("pathname error! path: %s\n", path); kprintf("pathname error! path: %s\n", path);
return -1; return -1;
} }
fd = vfs_table[index].op->open(pathname, flags); //modified by mingxuan 2020-10-18 fd = vfs_table[index].op->open(pathname, flags); // modified by mingxuan 2020-10-18
if(fd != -1) if (fd != -1)
{
p_proc_current->task.filp[fd]->dev_index = index;
}
else
{ {
p_proc_current -> task.filp[fd] -> dev_index = index;
} else {
kprintf(" error!\n"); kprintf(" error!\n");
} }
return fd; return fd;
} }
int do_vclose(int fd)
int do_vclose(int fd) { {
int index = p_proc_current->task.filp[fd]->dev_index; int index = p_proc_current->task.filp[fd]->dev_index;
return vfs_table[index].op->close(fd); //modified by mingxuan 2020-10-18 return vfs_table[index].op->close(fd); // modified by mingxuan 2020-10-18
} }
int do_vread(int fd, char *buf, int count) { int do_vread(int fd, char *buf, int count)
{
int index = p_proc_current->task.filp[fd]->dev_index; int index = p_proc_current->task.filp[fd]->dev_index;
return vfs_table[index].op->read(fd, buf, count); //modified by mingxuan 2020-10-18 return vfs_table[index].op->read(fd, buf, count); // modified by mingxuan 2020-10-18
} }
int do_vwrite(int fd, const char *buf, int count) { int do_vwrite(int fd, const char *buf, int count)
//modified by mingxuan 2019-5-23 {
// modified by mingxuan 2019-5-23
char s[512]; char s[512];
int index = p_proc_current->task.filp[fd]->dev_index; int index = p_proc_current->task.filp[fd]->dev_index;
const char *fsbuf = buf; const char *fsbuf = buf;
int f_len = count; int f_len = count;
int bytes; int bytes;
while(f_len) while (f_len)
{ {
int iobytes = min(512, f_len); int iobytes = min(512, f_len);
int i=0; int i = 0;
for(i=0; i<iobytes; i++) for (i = 0; i < iobytes; i++)
{ {
s[i] = *fsbuf; s[i] = *fsbuf;
fsbuf++; fsbuf++;
} }
//bytes = device_table[index].op->write(fd,s,iobytes); // bytes = device_table[index].op->write(fd,s,iobytes);
bytes = vfs_table[index].op->write(fd,s,iobytes); //modified by mingxuan 2020-10-18 bytes = vfs_table[index].op->write(fd, s, iobytes); // modified by mingxuan 2020-10-18
if(bytes != iobytes) if (bytes != iobytes)
{ {
return bytes; // TODO: Maybe problematic return bytes; // TODO: Maybe problematic
} }
@ -332,145 +349,166 @@ int do_vwrite(int fd, const char *buf, int count) {
return count; return count;
} }
int do_vunlink(const char *path) { int do_vunlink(const char *path)
{
int pathlen = strlen(path); int pathlen = strlen(path);
char pathname[MAX_PATH]; char pathname[MAX_PATH];
strcpy(pathname,(char *)path); strcpy(pathname, (char *)path);
pathname[pathlen] = 0; pathname[pathlen] = 0;
int index; int index;
index = get_index(pathname); index = get_index(pathname);
if(index==-1){ if (index == -1)
{
kprintf("pathname error!\n"); kprintf("pathname error!\n");
return -1; return -1;
} }
//return device_table[index].op->unlink(pathname); // return device_table[index].op->unlink(pathname);
return vfs_table[index].op->unlink(pathname); //modified by mingxuan 2020-10-18 return vfs_table[index].op->unlink(pathname); // modified by mingxuan 2020-10-18
} }
int do_vlseek(int fd, int offset, int whence) { int do_vlseek(int fd, int offset, int whence)
{
int index = p_proc_current->task.filp[fd]->dev_index; int index = p_proc_current->task.filp[fd]->dev_index;
//return device_table[index].op->lseek(fd, offset, whence); // return device_table[index].op->lseek(fd, offset, whence);
return vfs_table[index].op->lseek(fd, offset, whence); //modified by mingxuan 2020-10-18 return vfs_table[index].op->lseek(fd, offset, whence); // modified by mingxuan 2020-10-18
} }
//int do_vcreate(char *pathname) { // int do_vcreate(char *pathname) {
int do_vcreate(char *filepath) { //modified by mingxuan 2019-5-17 int do_vcreate(char *filepath)
//added by mingxuan 2019-5-17 { // modified by mingxuan 2019-5-17
// added by mingxuan 2019-5-17
int state; int state;
const char *path = filepath; const char *path = filepath;
int pathlen = strlen(path); int pathlen = strlen(path);
char pathname[MAX_PATH]; char pathname[MAX_PATH];
strcpy(pathname,(char *)path); strcpy(pathname, (char *)path);
pathname[pathlen] = 0; pathname[pathlen] = 0;
int index; int index;
index = get_index(pathname); index = get_index(pathname);
if(index == -1){ if (index == -1)
{
kprintf("pathname error! path: %s\n", path); kprintf("pathname error! path: %s\n", path);
return -1; return -1;
} }
state = vfs_table[index].op->create(pathname); //modified by mingxuan 2020-10-18 state = vfs_table[index].op->create(pathname); // modified by mingxuan 2020-10-18
if (state == 1) { if (state == 1)
{
kprintf(" create file success!"); kprintf(" create file success!");
} else { }
else
{
DisErrorInfo(state); DisErrorInfo(state);
} }
return state; return state;
} }
int do_vdelete(char *path) { int do_vdelete(char *path)
{
int pathlen = strlen(path); int pathlen = strlen(path);
char pathname[MAX_PATH]; char pathname[MAX_PATH];
strcpy(pathname,path); strcpy(pathname, path);
pathname[pathlen] = 0; pathname[pathlen] = 0;
int index; int index;
index = get_index(pathname); index = get_index(pathname);
if(index==-1){ if (index == -1)
{
kprintf("pathname error!\n"); kprintf("pathname error!\n");
return -1; return -1;
} }
//return device_table[index].op->delete(pathname); // return device_table[index].op->delete(pathname);
return vfs_table[index].op->delete(pathname); //modified by mingxuan 2020-10-18 return vfs_table[index].op->delete (pathname); // modified by mingxuan 2020-10-18
} }
int do_vopendir(char *path) { int do_vopendir(char *path)
{
int state; int state;
int pathlen = strlen(path); int pathlen = strlen(path);
char pathname[MAX_PATH]; char pathname[MAX_PATH];
strcpy(pathname,path); strcpy(pathname, path);
pathname[pathlen] = 0; pathname[pathlen] = 0;
int index; int index;
index = (int)(pathname[1]-'0'); index = (int)(pathname[1] - '0');
for(int j=0;j<= pathlen-3;j++) for (int j = 0; j <= pathlen - 3; j++)
{ {
pathname[j] = pathname[j+3]; pathname[j] = pathname[j + 3];
} }
state = f_op_table[index].opendir(pathname); state = f_op_table[index].opendir(pathname);
if (state == 1) { if (state == 1)
{
kprintf(" open dir success!"); kprintf(" open dir success!");
} else { }
else
{
DisErrorInfo(state); DisErrorInfo(state);
} }
return state; return state;
} }
int do_vcreatedir(char *path) { int do_vcreatedir(char *path)
{
int state; int state;
int pathlen = strlen(path); int pathlen = strlen(path);
char pathname[MAX_PATH]; char pathname[MAX_PATH];
strcpy(pathname,path); strcpy(pathname, path);
pathname[pathlen] = 0; pathname[pathlen] = 0;
int index; int index;
index = (int)(pathname[1]-'0'); index = (int)(pathname[1] - '0');
for(int j=0;j<= pathlen-3;j++) for (int j = 0; j <= pathlen - 3; j++)
{ {
pathname[j] = pathname[j+3]; pathname[j] = pathname[j + 3];
} }
state = f_op_table[index].createdir(pathname); state = f_op_table[index].createdir(pathname);
if (state == 1) { if (state == 1)
{
kprintf(" create dir success!"); kprintf(" create dir success!");
} else { }
else
{
DisErrorInfo(state); DisErrorInfo(state);
} }
return state; return state;
} }
int do_vdeletedir(char *path) { int do_vdeletedir(char *path)
{
int state; int state;
int pathlen = strlen(path); int pathlen = strlen(path);
char pathname[MAX_PATH]; char pathname[MAX_PATH];
strcpy(pathname,path); strcpy(pathname, path);
pathname[pathlen] = 0; pathname[pathlen] = 0;
int index; int index;
index = (int)(pathname[1]-'0'); index = (int)(pathname[1] - '0');
for(int j=0;j<= pathlen-3;j++) for (int j = 0; j <= pathlen - 3; j++)
{ {
pathname[j] = pathname[j+3]; pathname[j] = pathname[j + 3];
} }
state = f_op_table[index].deletedir(pathname); state = f_op_table[index].deletedir(pathname);
if (state == 1) { if (state == 1)
{
kprintf(" delete dir success!"); kprintf(" delete dir success!");
} else { }
else
{
DisErrorInfo(state); DisErrorInfo(state);
} }
return state; return state;

View File

@ -63,18 +63,33 @@ static inline void vga_set_video_start_addr(u32 addr)
enable_int(); enable_int();
} }
/***************************************************************************** /*****************************************************************************
* Write data directly to Video Memory cell * Write data directly to Video Memory cell
* *
* @param pos text mode position(pos*2 yourself) * @param pos text mode position(pos*2 yourself)
* @param dat data to be written, with format [ BG | FG | ASCII ] * @param dat data to be written, with format [ BG | FG | ASCII ]
*****************************************************************************/ *****************************************************************************/
static inline void vga_put_raw(u32 pos, u16 dat) { static inline void vga_put_raw(u32 pos, u16 dat)
u16* pch = (u16*)K_PHY2LIN(V_MEM_BASE + pos); {
u16 *pch = (u16 *)K_PHY2LIN(V_MEM_BASE + pos);
*pch = dat; *pch = dat;
} }
/*****************************************************************************
* copy a whole screen of text mode data into video memory, assume that screen
* width is 80 or 40
*
* @param src memory block with the same size as text mode video memory()
*****************************************************************************/
static inline void vga_flush_screen(void *src)
{
u32 *_src = src;
u32 *dst = (u32 *)K_PHY2LIN(V_MEM_BASE);
for (int i = 0; i < SCR_SIZE * sizeof(u16) / sizeof(u32); ++i)
{
*dst++ = *_src++;
}
}
/***************************************************************************** /*****************************************************************************
* copy a whole screen of text mode data into video memory, assume that screen * copy a whole screen of text mode data into video memory, assume that screen
@ -82,33 +97,22 @@ static inline void vga_put_raw(u32 pos, u16 dat) {
* *
* @param src memory block with the same size as text mode video memory() * @param src memory block with the same size as text mode video memory()
*****************************************************************************/ *****************************************************************************/
static inline void vga_flush_screen(void* src) { static inline void vga_flush_line(void *src, int line_no)
u32* _src = src; {
u32* dst = (u32*)K_PHY2LIN(V_MEM_BASE); u32 *_src = src;
for (int i = 0; i < SCR_SIZE * sizeof(u16) / sizeof(u32); ++ i) { u32 *dst = (u32 *)K_PHY2LIN(V_MEM_BASE + line_no * SCR_WIDTH * 2);
*dst ++ = *_src ++; for (int i = 0; i < SCR_WIDTH * sizeof(u16) / sizeof(u32); ++i)
{
*dst++ = *_src++;
} }
} }
static inline void vga_flush_blankline(int line_no)
/***************************************************************************** {
* copy a whole screen of text mode data into video memory, assume that screen u32 *dst = (u32 *)K_PHY2LIN(V_MEM_BASE + line_no * SCR_WIDTH * 2);
* width is 80 or 40 for (int i = 0; i < SCR_WIDTH * sizeof(u16) / sizeof(u32); ++i)
* {
* @param src memory block with the same size as text mode video memory() *dst++ = (BLANK << 16) | BLANK;
*****************************************************************************/
static inline void vga_flush_line(void* src, int line_no) {
u32* _src = src;
u32* dst = (u32*)K_PHY2LIN(V_MEM_BASE + line_no * SCR_WIDTH * 2);
for (int i = 0; i < SCR_WIDTH * sizeof(u16) / sizeof(u32); ++ i) {
*dst ++ = *_src ++;
}
}
static inline void vga_flush_blankline(int line_no) {
u32* dst = (u32*)K_PHY2LIN(V_MEM_BASE + line_no * SCR_WIDTH * 2);
for (int i = 0; i < SCR_WIDTH * sizeof(u16) / sizeof(u32); ++ i) {
*dst ++ = (BLANK << 16) | BLANK;
} }
} }
@ -121,7 +125,7 @@ void vga_tty_init(NTTY* tty) {
static int _cnt = 0; static int _cnt = 0;
assert(tty->driver_type == 1); assert(tty->driver_type == 1);
assert(tty->output_buf); assert(tty->output_buf);
vga_buf* vga = tty->output_buf; vga_buf *vga = tty->output_buf;
// vga->buf = (void*)do_kmalloc(sizeof(u16) * SCR_BUFSIZE); // vga->buf = (void*)do_kmalloc(sizeof(u16) * SCR_BUFSIZE);
vga->buf = (void*)pagebuf[_cnt ++]; vga->buf = (void*)pagebuf[_cnt ++];
// kprintf("malloced %p %p %p\n", vga->buf, &vga->buf, &vga->scr_top_line); // kprintf("malloced %p %p %p\n", vga->buf, &vga->buf, &vga->scr_top_line);
@ -129,46 +133,239 @@ void vga_tty_init(NTTY* tty) {
// buf->max_line = SCR_BUFSIZE / SCR_WIDTH; // buf->max_line = SCR_BUFSIZE / SCR_WIDTH;
vga->scr_top_line = vga->scr_cur_line = 0; vga->scr_top_line = vga->scr_cur_line = 0;
vga->head_line = 0; vga->head_line = 0;
u32* ptr_buf = (u32*) vga->buf; u32 *ptr_buf = (u32 *)vga->buf;
for (int i = 0; i < SCR_BUFSIZE * sizeof(u16) / sizeof(u32); ++i) { for (int i = 0; i < SCR_BUFSIZE * sizeof(u16) / sizeof(u32); ++i)
{
ptr_buf[i] = (BLANK << 16) | BLANK; // bg-black, fg-white, ascii-space ptr_buf[i] = (BLANK << 16) | BLANK; // bg-black, fg-white, ascii-space
} }
kprintf("%p 0x%x %d\n", vga->buf, ((u32*)vga->buf)[20], vga->scr_cur_line); kprintf("%p 0x%x %d\n", vga->buf, ((u32 *)vga->buf)[20], vga->scr_cur_line);
} }
#define INDEX(row, col) ((row) * SCR_WIDTH + (col)) #define INDEX(row, col) ((row)*SCR_WIDTH + (col))
#define NEXTLINE(row) NEXT(row, SCR_MAXLINE) #define NEXTLINE(row) (((row) + 1) % SCR_MAXLINE)
#define LASTLINE(row) LAST(row, SCR_MAXLINE) #define LASTLINE(row) (((row)-1) >= 0 ? ((row)-1) % SCR_MAXLINE : SCR_MAXLINE)
static void newline(vga_buf* vga) { static void newline(vga_buf *vgabuf)
vga->cur_col = 0; {
vgabuf->cur_col = 0;
// kprintf("bf %x\n", vgabuf->scr_cur_line); // kprintf("bf %x\n", vgabuf->scr_cur_line);
vga->scr_cur_line = NEXTLINE(vga->scr_cur_line); vgabuf->scr_cur_line = NEXTLINE(vgabuf->scr_cur_line);
// kprintf("af %x\n", vgabuf->scr_cur_line); // kprintf("af %x\n", vgabuf->scr_cur_line);
vga->cur_row = CYCLE_SUB(vga->scr_top_line, vga->scr_cur_line, SCR_MAXLINE); vgabuf->cur_row = abs(vgabuf->scr_cur_line - vgabuf->scr_top_line);
if (vga->cur_row == SCR_HEIGHT) { if (vgabuf->cur_row == SCR_HEIGHT)
{
// auto scroll // auto scroll
vga->scr_top_line = NEXTLINE(vga->scr_top_line); vgabuf->scr_top_line = NEXTLINE(vgabuf->scr_top_line);
if(vga->scr_cur_line == vga->head_line) { if (vgabuf->scr_cur_line == vgabuf->head_line)
vga->head_line = NEXTLINE(vga->head_line); {
vgabuf->head_line = NEXTLINE(vgabuf->head_line);
// remember to fill blank the old line // remember to fill blank the old line
u32* ptr_buf = (u32*) (vga->buf + sizeof(u16) * vga->head_line * SCR_WIDTH); u32 *ptr_buf = (u32 *)(vgabuf->buf + sizeof(u16) * vgabuf->head_line * SCR_WIDTH);
for (int i = 0; i < SCR_WIDTH * sizeof(u16) / sizeof(u32); ++i) { for (int i = 0; i < SCR_WIDTH * sizeof(u16) / sizeof(u32); ++i)
{
*ptr_buf++ = (BLANK << 16) | BLANK; // bg-black, fg-white, ascii-space *ptr_buf++ = (BLANK << 16) | BLANK; // bg-black, fg-white, ascii-space
} }
} }
} }
} }
void vga_tty_write(NTTY* tty, char ch) { static void nextcol(vga_buf *vgabuf)
{
vgabuf->cur_col++;
if (vgabuf->cur_col == SCR_WIDTH)
{
newline(vgabuf);
}
}
static void cursor_move(i16 move_row, i16 move_col, vga_buf *vgabuf)
{
vgabuf->scr_cur_line += move_row;
if (vgabuf->scr_cur_line < 0)
vgabuf->scr_cur_line = 0;
else if (vgabuf->scr_cur_line >= SCR_MAXLINE)
vgabuf->scr_cur_line = SCR_MAXLINE - 1;
vgabuf->cur_col += move_col;
if (vgabuf->cur_col < 0)
vgabuf->cur_col = 0;
else if (vgabuf->cur_col >= SCR_WIDTH)
vgabuf->cur_col = SCR_WIDTH - 1;
}
inline static void
param12vga_color(i16 *param)
{
u8 tmp = *param & 1;
*param &= 0b0110;
*param |= *param >> 2;
*param &= 0b0011;
*param |= tmp << 2;
}
static void set_color(vga_buf *vgabuf)
{
if (vgabuf->param1 == 0)
{
vgabuf->color = DEFAULT_CHAR_COLOR;
}
else if (vgabuf->param1 == 1)
{
vgabuf->color |= 0x8800;
}
else if (vgabuf->param1 == 2)
{
vgabuf->color &= 0x7700;
}
else if (30 <= vgabuf->param1 && vgabuf->param1 <= 37)
{
vgabuf->param1 -= 30;
param12vga_color(&(vgabuf->param1));
vgabuf->color = (vgabuf->color & 0xf8ff) | FOREGROUND(vgabuf->param1);
}
else if (40 <= vgabuf->param1 && vgabuf->param1 <= 47)
{
vgabuf->param1 -= 40;
param12vga_color(&(vgabuf->param1));
vgabuf->color = (vgabuf->color & 0x8fff) | BACKGROUND(vgabuf->param1);
}
else if (90 <= vgabuf->param1 && vgabuf->param1 <= 97)
{
vgabuf->param1 -= 90;
param12vga_color(&(vgabuf->param1));
vgabuf->param1 |= 0x8;
vgabuf->color = (vgabuf->color & 0xf0ff) | FOREGROUND(vgabuf->param1);
}
else if (100 <= vgabuf->param1 && vgabuf->param1 <= 107)
{
vgabuf->param1 -= 100;
param12vga_color(&(vgabuf->param1));
vgabuf->param1 |= 0x8;
vgabuf->color = (vgabuf->color & 0x0fff) | BACKGROUND(vgabuf->param1);
}
else
{
warn("unsupport CSI: color");
}
if (vgabuf->param2 == 0 && vgabuf->param1 == 0)
{
vgabuf->color = DEFAULT_CHAR_COLOR;
}
else if (vgabuf->param2 == 1)
{
vgabuf->color |= 0x8800;
}
else if (vgabuf->param2 == 2)
{
vgabuf->color &= 0x7700;
}
else if (30 <= vgabuf->param2 && vgabuf->param2 <= 37)
{
vgabuf->param2 -= 30;
param12vga_color(&(vgabuf->param2));
vgabuf->color = (vgabuf->color & 0xf8ff) | FOREGROUND(vgabuf->param2);
}
else if (40 <= vgabuf->param2 && vgabuf->param2 <= 47)
{
vgabuf->param2 -= 40;
param12vga_color(&(vgabuf->param2));
vgabuf->color = (vgabuf->color & 0x8fff) | BACKGROUND(vgabuf->param2);
}
else if (90 <= vgabuf->param2 && vgabuf->param2 <= 97)
{
vgabuf->param2 -= 90;
param12vga_color(&(vgabuf->param2));
vgabuf->param2 |= 0x8;
vgabuf->color = (vgabuf->color & 0xf0ff) | FOREGROUND(vgabuf->param2);
}
else if (100 <= vgabuf->param2 && vgabuf->param2 <= 107)
{
vgabuf->param2 -= 100;
param12vga_color(&(vgabuf->param2));
vgabuf->param2 |= 0x8;
vgabuf->color = (vgabuf->color & 0x0fff) | BACKGROUND(vgabuf->param2);
}
else
{
warn("unsupport CSI: color");
}
}
static void CSI_handler(u8 terminator, vga_buf *vgabuf)
{
vgabuf->CSI = CSI_ESC;
switch (terminator)
{
case 'A':
if (vgabuf->param1 == 0)
vgabuf->param1 == 1;
cursor_move(-vgabuf->param1, 0, vgabuf);
break;
case 'B':
if (vgabuf->param1 == 0)
vgabuf->param1 == 1;
cursor_move(+vgabuf->param1, 0, vgabuf);
break;
case 'C':
if (vgabuf->param1 == 0)
vgabuf->param1 == 1;
cursor_move(0, -vgabuf->param1, vgabuf); // nothing
break;
case 'D':
if (vgabuf->param1 == 0)
vgabuf->param1 == 1;
cursor_move(0, +vgabuf->param1, vgabuf);
break;
case 'E':
if (vgabuf->param1 == 0)
vgabuf->param1 == 1;
cursor_move(+vgabuf->param1, -vgabuf->cur_col, vgabuf);
break;
case 'F':
if (vgabuf->param1 == 0)
vgabuf->param1 == 1;
cursor_move(-vgabuf->param1, -vgabuf->cur_col, vgabuf);
break;
case 'G': // added
cursor_move(0, vgabuf->param1 - vgabuf->cur_col, vgabuf);
break;
case 'H':
cursor_move(vgabuf->param1 - vgabuf->scr_cur_line, vgabuf->param1 - vgabuf->cur_col, vgabuf);
break;
case 'J':
break;
case 'K':
break;
case 'S':
break;
case 'T':
break;
case 'm':
set_color(vgabuf);
break;
}
}
void vga_tty_write(NTTY *tty, char ch)
{
// assert(tty->driver_type == 1); // assert(tty->driver_type == 1);
// assert(tty->output_buf); // assert(tty->output_buf);
vga_buf* vga = tty->output_buf; vga_buf *vga = tty->output_buf;
u16* buf = vga->buf; u16 *buf = vga->buf;
// kprintf("vga_tty_write %c to %d %d\n", ch, vga->scr_cur_line, vga->cur_col); // kprintf("vga_tty_write %c to %d %d\n", ch, vga->scr_cur_line, vga->cur_col);
if (vga->CSI == CSI_ESC)
{
switch (ch) switch (ch)
{ {
case '\t':
if (INDEX(vga->scr_cur_line, vga->cur_col) == SCR_BUFSIZE - 1)
break;
while (vga->cur_col % 4 != 1)
{
nextcol(vga);
}
break;
case '\n': case '\n':
newline(vga); newline(vga);
break; break;
@ -178,18 +375,73 @@ void vga_tty_write(NTTY* tty, char ch) {
case '\b': case '\b':
// this implementation is mimic to usual linux shell // this implementation is mimic to usual linux shell
// it moves cursor left but neither crosses line nor delete character // it moves cursor left but neither crosses line nor delete character
if (vga->cur_col > 0) { if (vga->cur_col > 0)
vga->cur_col --; {
vga->cur_col--;
} }
break; break;
case '\x1b':
vga->CSI = CSI_BRACKET;
break;
default: default:
if (vga->color == 0)
{
buf[INDEX(vga->scr_cur_line, vga->cur_col)] = MAKE_CELL(DEFAULT_CHAR_COLOR, ch); buf[INDEX(vga->scr_cur_line, vga->cur_col)] = MAKE_CELL(DEFAULT_CHAR_COLOR, ch);
vga->cur_col ++;
if (vga->cur_col == SCR_WIDTH) {
newline(vga);
} }
else
{
buf[INDEX(vga->scr_cur_line, vga->cur_col)] = MAKE_CELL(vga->color, ch);
}
// buf[INDEX(vga->scr_cur_line, vga->cur_col)] = MAKE_CELL(DEFAULT_CHAR_COLOR, ch);
nextcol(vga);
break; break;
} }
}
else if (vga->CSI == CSI_BRACKET)
{
switch (ch)
{
case '[':
vga->CSI = CSI_PARAM1;
vga->param1 = vga->param2 = 0;
break;
default:
vga->CSI = CSI_ESC;
break;
}
}
else
{
switch (ch)
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
if (vga->CSI == CSI_PARAM1)
vga->param1 = vga->param1 * 10 + ch - '0';
else if (vga->CSI == CSI_PARAM2)
vga->param2 = vga->param2 * 10 + ch - '0';
else
; // do nothing
break;
case ';':
vga->CSI = CSI_PARAM2;
break;
default:
if (!(0x20 <= ch && ch <= 0x7e))
vga->CSI = CSI_ESC;
if (0x40 <= ch && ch <= 0x7e)
CSI_handler(ch, vga);
break;
}
}
vga->cur_row = CYCLE_SUB(vga->scr_top_line, vga->scr_cur_line, SCR_MAXLINE); vga->cur_row = CYCLE_SUB(vga->scr_top_line, vga->scr_cur_line, SCR_MAXLINE);
// kprintf("row: %d; ", vga->cur_row); // kprintf("row: %d; ", vga->cur_row);
} }
@ -212,49 +464,69 @@ void vga_tty_flush(NTTY* tty) {
u16* buf = vga->buf; u16* buf = vga->buf;
int i, cur_line; int i, cur_line;
vga_set_cursor(INDEX(vga->cur_row, vga->cur_col)); vga_set_cursor(INDEX(vga->cur_row, vga->cur_col));
if (vga->cur_row == SCR_WIDTH - 1) { if (vga->cur_row == SCR_WIDTH - 1)
{
vga_flush_screen(&buf[INDEX(vga->scr_top_line, 0)]); vga_flush_screen(&buf[INDEX(vga->scr_top_line, 0)]);
} }
else { else
{
cur_line = vga->scr_top_line; cur_line = vga->scr_top_line;
for (i = 0; i <= vga->cur_row; ++ i){ for (i = 0; i <= vga->cur_row; ++i)
{
vga_flush_line(&buf[INDEX(cur_line, 0)], i); vga_flush_line(&buf[INDEX(cur_line, 0)], i);
cur_line = NEXTLINE(cur_line); cur_line = NEXTLINE(cur_line);
} }
for (; i < SCR_WIDTH; ++ i) { for (; i < SCR_WIDTH; ++i)
{
vga_flush_blankline(i); vga_flush_blankline(i);
} }
} }
// kprintf("flush: row=%d, top=%d, cur=%d\n", vga->cur_row, vga->scr_top_line, vga->scr_cur_line); // kprintf("flush: row=%d, top=%d, cur=%d\n", vga->cur_row, vga->scr_top_line, vga->scr_cur_line);
} }
void vga_tty_scroll(NTTY* tty, int direction) { void vga_tty_scroll(NTTY *tty, int direction)
vga_buf* vga = tty->output_buf; {
u16* buf = vga->buf; vga_buf *vga = tty->output_buf;
if (direction > 0) { u16 *buf = vga->buf;
if (direction > 0)
{
// down // down
if (vga->scr_top_line == vga->scr_cur_line) return; if (vga->scr_top_line == vga->scr_cur_line)
return;
vga->scr_top_line = NEXTLINE(vga->scr_top_line); vga->scr_top_line = NEXTLINE(vga->scr_top_line);
} }
else { else
if (vga->scr_top_line == vga->head_line) return; {
if (vga->scr_top_line == vga->head_line)
return;
vga->scr_top_line = LASTLINE(vga->scr_top_line); vga->scr_top_line = LASTLINE(vga->scr_top_line);
} }
vga->cur_row = abs(vga->scr_cur_line - vga->scr_top_line); vga->cur_row = abs(vga->scr_cur_line - vga->scr_top_line);
if (vga->cur_row >= SCR_HEIGHT) { if (vga->cur_row >= SCR_HEIGHT)
{
vga_disable_cursor(); vga_disable_cursor();
} }
else { else
{
vga_enable_cursor(0, 15); vga_enable_cursor(0, 15);
} }
} }
void vga_scroll_to_cur(NTTY* tty) { void vga_scroll_to_cur(NTTY *tty)
vga_buf* vga = tty->output_buf; {
u16* buf = vga->buf; vga_buf *vga = tty->output_buf;
u16 *buf = vga->buf;
// vga->scr_top_line = vga->scr_cur_line // vga->scr_top_line = vga->scr_cur_line
} }
void vga_tty_select(NTTY* tty) { void vga_ttroll_to_cur(NTTY *tty)
{
vga_buf *vga = tty->output_buf;
u16 *buf = vga->buf;
// vga->scr_top_line = vga->scr_cur_line
}
void vga_tty_select(NTTY *tty)
{
// //
} }

View File

@ -16,11 +16,14 @@ int main(int arg, char *argv[])
char buf[1024]; char buf[1024];
int pid; int pid;
int times = 0; int times = 0;
for (int i = 0; i < 20; ++ i) { for (int i = 0; i < 20; ++i)
{
printf("test %d\n", i); printf("test %d\n", i);
} }
for (int i = 0; i < 2; ++ i) { for (int i = 0; i < 2; ++i)
printf("1111111111"); {
printf("\x1b[42;31m1111111111");
// printf("\x1b[m1111111111");
printf("2222222222"); printf("2222222222");
printf("3333333333"); printf("3333333333");
printf("4444444444"); printf("4444444444");
@ -31,6 +34,7 @@ int main(int arg, char *argv[])
printf("9999999999\r\b\b\n"); printf("9999999999\r\b\b\n");
} }
while(1); while (1)
;
return 0; return 0;
} }