Merge branch 'master' of http://101.42.106.131:30303/Catfood/BigOS
This commit is contained in:
commit
4bd7c1e46d
@ -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_ */
|
||||||
@ -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_ */
|
||||||
108
kernel/console.c
108
kernel/console.c
@ -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);
|
||||||
}
|
}
|
||||||
626
kernel/fs.c
626
kernel/fs.c
File diff suppressed because it is too large
Load Diff
397
kernel/main.c
397
kernel/main.c
@ -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.
|
||||||
|
|||||||
31
kernel/tty.c
31
kernel/tty.c
@ -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]);
|
||||||
|
|||||||
328
kernel/vfs.c
328
kernel/vfs.c
@ -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;
|
||||||
|
|||||||
412
kernel/vga.c
412
kernel/vga.c
@ -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)
|
||||||
|
{
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
12
user/test.c
12
user/test.c
@ -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;
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue
Block a user