linux 0.11 内核学习 -- console.c,控制台

本文详细解析了Linux 0.11内核中的console.c文件,主要涉及控制台显示操作,包括初始化、光标定位、屏幕滚动等功能。通过分析代码,解释了如何处理不同类型的显示器,如MDA、CGA、EGA/VGA,并提供了滚动屏幕的实现细节,如向上和向下滚动。同时,文中提到了ESC转义序列的处理,包括光标移动、字符删除和插入等操作。
摘要由CSDN通过智能技术生成

参考《linux内核完全注释》和网上相关文章

/*

 * 控制台显示操作

 */

/*

 *  linux/kernel/console.c

 *

 *  (C) 1991  Linus Torvalds

 */

 

/*

 * console.c

 *

 * This module implements the console io functions

 * 'void con_init(void)'

 * 'void con_write(struct tty_queue * queue)'

 * Hopefully this will be a rather complete VT102 implementation.

 *

 * Beeping thanks to John T Kohl.

 */

/**********************

 * con_init con_write *

 **********************/

/*

 *  NOTE!!! We sometimes disable and enable interrupts for a short while

 * (to put a word in video IO), but this will work even for keyboard

 * interrupts. We know interrupts aren't enabled when getting a keyboard

 * interrupt, as we use trap-gates. Hopefully all is well.

 */

 

/*

 * Code to check for different video-cards mostly by Galen Hunt,

 * <g-hunt@ee.utah.edu>

 */

 

#include <linux/sched.h>

#include <linux/tty.h> // 定义tty_struct结构,串行通信方面的参数和常量

#include <asm/io.h> // 硬件对应的汇编io指令

#include <asm/system.h>

 

/*

 * These are set up by the setup-routine at boot-time:

 */

 

#define ORIG_X (*(unsigned char *)0x90000) // 光标列号

#define ORIG_Y (*(unsigned char *)0x90001) // 光标行号

#define ORIG_VIDEO_PAGE (*(unsigned short *)0x90004) // 显示页面

#define ORIG_VIDEO_MODE ((*(unsigned short *)0x90006) & 0xff) // 显示模式

#define ORIG_VIDEO_COLS (((*(unsigned short *)0x90006) & 0xff00) >> 8) // 字符列数

#define ORIG_VIDEO_LINES (25) // 字符行数

#define ORIG_VIDEO_EGA_AX (*(unsigned short *)0x90008) // ??

#define ORIG_VIDEO_EGA_BX (*(unsigned short *)0x9000a) // 显示内存大小和色彩模式

#define ORIG_VIDEO_EGA_CX (*(unsigned short *)0x9000c) // 显示卡特性参数

 

#define VIDEO_TYPE_MDA 0x10 /* Monochrome Text Display,单色文本 */

#define VIDEO_TYPE_CGA 0x11 /* CGA Display,CGA 显示器 */

#define VIDEO_TYPE_EGAM 0x20 /* EGA/VGA in Monochrome Mode,EGA/VGA 单色 */

#define VIDEO_TYPE_EGAC 0x21 /* EGA/VGA in Color Mode,EGA/VGA 彩色 */

 

#define NPAR 16

 

extern void keyboard_interrupt(void); // 键盘中断处理程序

/* 全局变量,指示显示器的相关信息 */

static unsigned char video_type; /* Type of display being used */

static unsigned long video_num_columns; /* Number of text columns */

static unsigned long video_size_row; /* Bytes per row,每行使用的字节数 */

static unsigned long video_num_lines; /* Number of test lines,屏幕文本行数 */

static unsigned char video_page; /* Initial video page,初始显示页面 */

static unsigned long video_mem_start; /* Start of video RAM */

static unsigned long video_mem_end; /* End of video RAM (sort of) */

static unsigned short video_port_reg; /* Video register select port */

/* 显示控制索引寄存器端口 */

static unsigned short video_port_val; /* Video register value port */

static unsigned short video_erase_char; /* Char+Attrib to erase with,擦除字符属性与字符 */

/* 下面的全局变量是屏幕卷屏操作所使用 */

static unsigned long origin; /* Used for EGA/VGA fast scroll */ // 滚屏起始内存地址

static unsigned long scr_end; /* Used for EGA/VGA fast scroll */ // 滚屏末端内存地址

static unsigned long pos; // 当前光标位置相对于显存的位置

static unsigned long x,y; // 当前光标

static unsigned long top,bottom; // 滚动时顶行行号和底行行号

/**************************************************************/

static unsigned long state=0; // 处理ESC 转义序列时的当前进行到哪

static unsigned long npar,par[NPAR]; // 放ESC 序列的中间处理参数

/************************************************************/

static unsigned long ques=0;

static unsigned char attr=0x07; // char

 

static void sysbeep(void);

 

/*

 * this is what the terminal answers to a ESC-Z or csi0c

 * query (= vt100 response).

 */

#define RESPONSE "/033[?1;2c"

 

/* NOTE! gotoxy thinks x==video_num_columns is ok */

/* 更新当前光标位置 */

/*

 * |----------------------------------------------------------> x

 * |             video_size_row

 * |--------------------------------------| -|------> top顶行行号

 * |--------------------------------------|  |

 * |                                      |  |

 * |        *     *         *             |  | --> video_num_row

 *            P(x, y)                        | 

 * |--------------------------------------| -|------> button底行行号

 * |--------------------------------------|

 * |                  |

 * |             video_num_columns

 * |

 * | y

 *   

 * all video memory = video_size_row * video_num_row

 * the screen point P(x, y) is mapping the main memory 

 * video_mem_start + y * video_size_row + (x << 1)

 */

static inline void gotoxy(unsigned int new_x,unsigned int new_y)

{

if (new_x > video_num_columns || new_y >= video_num_lines)

return; // 错误检查

x=new_x; // 更新x,y

y=new_y;

pos=origin + y*video_size_row + (x<<1); // 重新计算全局变量pos值

}

/* 设置滚屏起始显示内存地址 */

static inline void set_origin(void)

{

cli();

outb_p(12, video_port_reg); // 向择显示控制数据寄存器r12写入卷屏起始地址高字节

outb_p(0xff&((origin-video_mem_start)>>9), video_port_val);

outb_p(13, video_port_reg); // 向显示控制数据寄存器r13写入卷屏起始地址底字节

outb_p(0xff&((origin-video_mem_start)>>1), video_port_val);

sti();

}

/* 向上卷动一行 */

static void scrup(void)

{

/*

 * 我们可以认为的是显存就是一片内存区域,显示器在决定显示部分时,根据的是

 * 显示控制器的的内存

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值