• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            天衣有縫

            冠蓋滿京華,斯人獨憔悴~
            posts - 35, comments - 115, trackbacks - 0, articles - 0
               :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

            jinix內核虛擬控制臺實現(原創)

            Posted on 2007-07-10 20:15 天衣有縫 閱讀(2037) 評論(2)  編輯 收藏 引用 所屬分類: os stuff

            jinix是小弟正在實現的一個c++ kernel,因為調試緣故,所以早早的把控制臺部分調出來了,以便于后來的調試。代碼使用c++寫的,如果使用c寫內核也很容易移植過去。轉載請保留原 創:http://www.shnenglu.com/jinglexymail & msn: jinglexy at yahoo dot com dot cn。這部分代碼是在內存管理之前實現的,所以沒有做到任意個數虛擬控制臺(內核在編譯時候確定個數),并且每個控制臺顯存地址固定起來了。如果要實現也 比較簡單:啟動時候初始化一個控制臺,在MM初始化完后初始化其他控制臺,每個控制臺包含自己的顯存緩沖區,切換控制臺的時候將該緩沖區拷貝到顯存中即 可。

            文件:textio.h, textio.cpp, ostream.h, ostream.cpp
            textio.h
            源文件如下:

                 1: #ifndef __JINIX_TEXTIO_H 
            2: #define __JINIX_TEXTIO_H
            3: #include <jinix/types.h>
            4:
            5: /* 在字符模式下,適配器使用0xB8000-0xBF000作為視頻內存。
            6: * 通常我們處于80x25大小屏幕,有16種顏色。
            7: * 由于一個屏幕只需要80x25x2個字節,即4k,所以該視頻內存可以分為多個頁。
            8: * 我們使用所有的頁,但是當前只能有一個頁面可見。
            9: * 為了顯示一個字符,將用到2個字節,一個字節是字符值(地址為N),
            10: * 另一個字節是字符屬性(即顏色,地址為N + 1)。屬性字節定義如下:
            11: *
            12: * Bit 7 閃爍
            13: * Bits 6-4 背景色
            14: * Bit 3 明亮模式(0為暗,1為亮)
            15: * Bit3 2-0 前景色:分別是黑,蘭,綠,青,洋紅,深粉,深黃,灰色
            16: *
            17: * 操作端口基址:0x3d4h, 0x3d5h
            18: * 參考資料:osd文檔中的osd/cons/index.htm
            19: * CGA顯示模式,顯存從0xB8000開始一共32kb字節,在jinix中每個虛擬控制臺只使用4k字節(80x25x2),
            20: * 且不考慮滾屏操作(為了簡單處理),所以最多可以有8個控制臺
            21: */

            22: typedef enum {
            23: BLACK, BLUE, GREEN, CYAN,
            24: RED, MAGENTA, BROWN, GRAY,
            25: DARKGRAY, LIGHTBLUE, LIGHTGREEN, LIGHTCYAN,
            26: LIGHTRED, LIGHTMAGENTA, YELLOW, WHITE
            27: } TextColor;
            28:
            29: const int CGA_VIDEO_PTR = 0xB8000;
            30: const int CGA_CONSOLE_SIZE = 4000;
            31: const char BLANK_CHAR = ' ';
            32:
            33: class TextIO
            34: {
            35: public:
            36: TextIO() ;
            37: ~TextIO() ;
            38: void init_page(int page); /* must call first!!! */
            39: void move_cursor(void);
            40: void move_page(void);
            41: void setxy(int newx, int newy);
            42:
            43: int getx() { return x; }
            44: int gety() { return y; }
            45:
            46: void scrollup();
            47: void clear();
            48:
            49: void set_fg(TextColor fg);
            50: void set_bg(TextColor bg);
            51:
            52: void putstr(char *s);
            53: /* inline */void putchar(char c);
            54:
            55: private:
            56: int x, y;
            57: char colors;
            58: char *pvideo_start; /* 虛擬控制臺顯存首地址 */
            59: /* struct termios termios; posix compatible later... */
            60: };
            61:
            62: #endif
            63:
            64:


            這個文件完成顯存的一些字符操作,及顯存頁面切換,滾屏也很簡單。沒有加入posix兼容的一些特性,
            還沒有想好是否加在這里。rs232也會使用終端特性,所以考慮后期將字符設備驅動抽象成一個基類,
            作為textio類的父類。有什么好的想法可以和我討論:http://www.shnenglu.com/jinglexy

            ostream.h
            源文件:

            1: #ifndef __JINIX_OSTREAM_H
            2: #define __JINIX_OSTREAM_H
            3: #include <jinix/textio.h>
            4:
            5: /* format flags */
            6: #define boolalpha 0x0001 /* 未實現 */
            7: #define showbase 0x0002
            8: #define showpoint 0x0004 /* 未實現 */
            9: #define showpos 0x0008 /* 未實現 */
            10: #define skipws 0x0010 /* 未實現 */
            11: #define unitbuf 0x0020 /* 未實現 */
            12: #define uppercase 0x0040 /* 未實現 */
            13: #define dec 0x0080
            14: #define hex 0x0100
            15: #define oct 0x0200
            16: #define bin 0x0400
            17: #define internal 0x0800 /* 未實現 */
            18: #define left 0x1000 /* 未實現 */
            19: #define right 0x2000 /* 未實現 */
            20:
            21: class OStream : public TextIO
            22: {
            23: public:
            24: OStream();
            25: OStream& operator <<(char *str);
            26: OStream& operator <<(char c);
            27: OStream& operator <<(unsigned char *str);
            28: OStream& operator <<(unsigned char c);
            29: OStream& operator <<(int i);
            30: OStream& operator <<(unsigned int i);
            31: OStream& operator <<(long i);
            32: OStream& operator <<(unsigned long i);
            33: OStream& operator <<(long long i);
            34: OStream& operator <<(unsigned long long i);
            35: void flags(int f);
            36:
            37: private:
            38: int current_flags; /* 顯示模式: 進制數, 對齊形式等 */
            39: };
            40:
            41: #define cout __vconsole[__cur_console]
            42: void switch_console(int console);
            43:
            44: /* 單元測試 */
            45: void ostream_dotest(void);
            46:
            47: /* 不要使用下面兩個全局變量 */
            48: extern class OStream __vconsole[];
            49: extern int __cur_console;
            50: #endif
            51:
            52:

            不熟悉設計模式,所以結構比較混亂,好的模式應該可以規避這些不雅的代碼吧,呵呵

            textio.cpp
            源文件:

            1: #include <asm/portio.h>
            2: #include <asm/system.h>
            3: #include <jinix/tty.h>
            4: #include <jinix/textio.h>
            5:
            6: TextIO::TextIO()
            7: {
            8: x = 0;
            9: y = 0;
            10: colors = TTY_CHAR_ATTRIBUTE;
            11: pvideo_start = (char*)NULL;
            12: }
            13:
            14: TextIO::~TextIO()
            15: {
            16: }
            17:
            18: void TextIO::init_page(int page)
            19: {
            20: if (page < 0 || page > VIRTUAL_CONSOLE_COUNT - 1)
            21: return;
            22:
            23: /* after init, console[0].pvideo_start is 0xb8000;
            24: * console[1].pvideo_start is 0xb8fa0
            25: * console[2].pvideo_start is 0xb9f40
            26: * console[3].pvideo_start is 0xbaee0
            27: */

            28: pvideo_start = (char*)CGA_VIDEO_PTR + page * CGA_CONSOLE_SIZE;
            29: /* debug(if not, gdb fly out): */ page++;
            30: }
            31:
            32: void TextIO::move_cursor(void)
            33: {
            34: int temp;
            35: temp = y * TTY_COLUMNS_NR + x;
            36:
            37: /* disable interrupt */
            38: __cli();
            39: PortIO::outportb(0x3D4, 14);
            40: PortIO::outportb(0x3D5, temp >> 8);
            41: PortIO::outportb(0x3D4, 15);
            42: PortIO::outportb(0x3D5, temp);
            43: /* enable interrupt */
            44: __sti();
            45: }
            46:
            47: void TextIO::move_page(void)
            48: {
            49: int temp;
            50: temp = (int)(pvideo_start - CGA_VIDEO_PTR) / 2;
            51:
            52: /* disable interrupt */
            53: __cli();
            54: PortIO::outportb(0x3D4, 12);
            55: PortIO::outportb(0x3D5, temp >> 8);
            56: PortIO::outportb(0x3D4, 13);
            57: PortIO::outportb(0x3D5, temp);
            58: /* enable interrupt */
            59: __sti();
            60: }
            61:
            62: void TextIO::setxy(int newx, int newy)
            63: {
            64: if (newx >= 0 && newx < TTY_COLUMNS_NR)
            65: x = newx;
            66:
            67: if (newy >= 0 && newy < TTY_LINES_NR)
            68: y = newy;
            69: }
            70:
            71: /* it will scroll only one line */
            72: void TextIO::scrollup()
            73: {
            74: char *src, *dst;
            75: int i, j;
            76:
            77: dst = pvideo_start;
            78: src = pvideo_start + TTY_COLUMNS_NR * 2;
            79:
            80: for (i = 0; i < TTY_LINES_NR - 1; i++)
            81: for (j = 0; j < TTY_COLUMNS_NR * 2; j++) /* every char 2 bytes */
            82: *dst++ = *src++;
            83:
            84: /* new line */
            85: for (i = 0; i < TTY_COLUMNS_NR; i++) {
            86: *dst++ = BLANK_CHAR;
            87: *dst++ = colors;
            88: }
            89: }
            90:
            91: void TextIO::clear(void)
            92: {
            93: int i;
            94: char *src;
            95:
            96: src = pvideo_start;
            97: for (i = 0; i < TTY_COLUMNS_NR * TTY_LINES_NR; i++) {
            98: *src++ = BLANK_CHAR;
            99: *src++ = colors;
            100: }
            101:
            102: setxy(0, 0);
            103: move_cursor();
            104: }
            105:
            106: void TextIO::set_fg(TextColor fg)
            107: {
            108: colors = (colors & 0xf0) | (fg & 0x0f);
            109: }
            110:
            111: void TextIO::set_bg(TextColor bg)
            112: {
            113: colors = (colors & 0x0f) | ((bg << 4) & 0xf0);
            114: }
            115:
            116: void TextIO::putstr(char *s)
            117: {
            118: while (*s)
            119: putchar(*s++);
            120: }
            121:
            122: /* extern inline */void TextIO::putchar(char c)
            123: {
            124: int t;
            125:
            126: switch(c) {
            127: case '\r':
            128: {
            129: int i;
            130: x = 0;
            131:
            132: /* 清除一行 */
            133: t = ((x + y * TTY_COLUMNS_NR) << 1);
            134: for(i = 0 ; i < TTY_COLUMNS_NR; i++) {
            135: *(pvideo_start + t + (i << 1)) = BLANK_CHAR;
            136: *(pvideo_start + t + (i << 1) + 1) = colors;
            137: }
            138: break;
            139: }
            140:
            141: case '\n':
            142: {
            143: x = 0;
            144: y++;
            145: break;
            146: }
            147:
            148: case '\t':
            149: {
            150: if (x + TTY_TABWIDTH >= TTY_COLUMNS_NR) {
            151: x = (x + TTY_TABWIDTH - TTY_COLUMNS_NR);
            152: y++;
            153: } else {
            154: x += TTY_TABWIDTH;
            155: }
            156:
            157: break;
            158: }
            159:
            160: case '\b':
            161: {
            162: t = x + y * TTY_COLUMNS_NR;
            163:
            164: if (t <= 0)
            165: break;
            166: t--;
            167:
            168: if (x > 0) {
            169: x--;
            170: } else {
            171: y--;
            172: x = TTY_COLUMNS_NR - 1;
            173: }
            174:
            175: *(pvideo_start + (t << 1)) = BLANK_CHAR;
            176: *(pvideo_start + (t << 1) + 1) = colors;
            177: break;
            178: }
            179:
            180: default:
            181: {
            182: if(c < ' ') break; /* only print visible char */
            183: t = x + y * TTY_COLUMNS_NR;
            184:
            185: *(pvideo_start + (t << 1)) = c;
            186: *(pvideo_start + (t << 1) + 1) = colors;
            187: x++;
            188:
            189: if(x == 80) {
            190: x = 0;
            191: y++;
            192: }
            193: break;
            194: }
            195: }
            196:
            197: if (TTY_LINES_NR == y) {
            198: scrollup();
            199: y--;
            200: }
            201: move_cursor();
            202: }
            203:
            204:

            需要注意的是多個端口同時操作需要關閉中斷,否則一旦在多任務中被調度出去,后果很嚴重,呵呵

            1: #include <jinix/tty.h>
            2: #include <jinix/ostream.h>
            3: #include <asm/string.h>
            4:
            5: class OStream __vconsole[VIRTUAL_CONSOLE_COUNT];
            6: int __cur_console; /* 當前控制臺 */
            7:
            8: OStream::OStream()
            9: {
            10: current_flags = dec;
            11: }
            12:
            13: OStream& OStream::operator <<(char *str)
            14: {
            15: putstr(str);
            16: return *this;
            17: }
            18:
            19: OStream& OStream::operator <<(char c)
            20: {
            21: putchar(c);
            22: return *this;
            23: }
            24:
            25: OStream& OStream::operator <<(unsigned char *str)
            26: {
            27: putstr((char *)str);
            28: return *this;
            29: }
            30:
            31: OStream& OStream::operator <<(unsigned char c)
            32: {
            33: putchar((char)c);
            34: return *this;
            35: }
            36:
            37: OStream& OStream::operator <<(int i)
            38: {
            39: char buf[33]; /* 2進制支持 */
            40:
            41: if (current_flags & dec)
            42: itoa(buf, 10, i);
            43: else if (current_flags & hex)
            44: itoa(buf, 16, i);
            45: else if (current_flags & oct)
            46: itoa(buf, 8, i);
            47: else if (current_flags & bin)
            48: itoa(buf, 2, i);
            49:
            50: if (current_flags & hex && current_flags & showbase)
            51: putstr("0x");
            52:
            53: putstr(buf);
            54: return *this;
            55: }
            56:
            57: OStream& OStream::operator <<(unsigned int i)
            58: {
            59: *this << (int)i;
            60: return *this;
            61: }
            62:
            63: OStream& OStream::operator <<(long i)
            64: {
            65: *this << (int)i;
            66: return *this;
            67: }
            68:
            69: OStream& OStream::operator <<(unsigned long i)
            70: {
            71: *this << (int)i;
            72: return *this;
            73: }
            74:
            75: OStream& OStream::operator <<(long long i)
            76: {
            77: char buf[65]; /* 2進制支持 */
            78:
            79: if (current_flags & dec)
            80: itoa(buf, 10, i);
            81: else if (current_flags & hex)
            82: itoa(buf, 16, i);
            83: else if (current_flags & oct)
            84: itoa(buf, 8, i);
            85: else if (current_flags & bin)
            86: itoa(buf, 2, i);
            87:
            88: if (current_flags & hex && current_flags & showbase)
            89: putstr("0x");
            90:
            91: putstr(buf);
            92: return *this;
            93: }
            94:
            95: OStream& OStream::operator <<(unsigned long long i)
            96: {
            97: *this << (long long)i;
            98: return *this;
            99: }
            100:
            101: void OStream::flags(int f)
            102: {
            103: current_flags = f;
            104: }
            105:
            106: void switch_console(int console)
            107: {
            108: if (console < 0 || console > VIRTUAL_CONSOLE_COUNT - 1)
            109: return;
            110:
            111: /* set current console */
            112: __cur_console = console;
            113:
            114: /* move page */
            115: cout.move_page();
            116:
            117: /* move cursor */
            118: cout.move_cursor();
            119: }
            120:
            121: /* only call when init */
            122: void __kernel_init_switch_console(int console)
            123: {
            124: if (console < 0 || console > VIRTUAL_CONSOLE_COUNT - 1)
            125: return;
            126:
            127: /* set current console */
            128: __cur_console = console;
            129: }
            130:
            131: void ostream_dotest(void)
            132: {
            133: int i;
            134:
            135: i = 0;
            136: {
            137: /* 虛擬控制臺切換測試 */
            138: for(i = 0; i < VIRTUAL_CONSOLE_COUNT; i++) {
            139: switch_console(i);
            140: cout.putstr("0123456789abcdefghijklmnoprfdsafdieqxzcvaeax");
            141: }
            142:
            143: for(i = 0; i < VIRTUAL_CONSOLE_COUNT; i++) {
            144: switch_console(i);
            145: cout.putstr("0123456789abcdefghijklmnoprfdsafdieqxzcvaeax");
            146: }
            147:
            148: switch_console(0);
            149: cout.putstr("00000000000000000000000");
            150: switch_console(1);
            151: cout.putstr("11111111111111111111111");
            152: switch_console(2);
            153: cout.putstr("22222222222222222222222");
            154: switch_console(3);
            155: cout.putstr("33333333333333333333333");
            156: }
            157:
            158: {
            159: /* 復雜字符串輸出測試 */
            160: switch_console(0);
            161: for(i = 0; i < 20; i++) {
            162: cout.putstr("++++++++++++++++++++");
            163: cout.putstr("++++++++++++++++++++");
            164: cout.putstr("++++++++++++++++++++");
            165: cout.putstr("++++++++++++++++++++");
            166: }
            167:
            168: cout.putstr("\r");
            169: cout.putstr("00000000000000000000000\n");
            170: cout.putstr("0\t0\t0\t0\t0\t0\t0\t0\t0\t0\ta\n");
            171: cout.putstr("+_+_+_+_+_+_+_+_+_+_+_");
            172: cout.putstr("\b\b\b\b\b*&*&*&*&*&*&*&*&");
            173: i++;
            174: }
            175:
            176: {
            177: /* 清屏,滾屏,及滾屏對切換虛擬控制臺的影響測試 */
            178: cout.clear();
            179: for(i = 0; i < 24; i++) {
            180: cout.putstr("++++++++++++++++++++");
            181: cout.putstr("++++++++++++++++++++");
            182: cout.putstr("++++++++++++++++++++");
            183: cout.putstr("++++++++++++++++++++");
            184: }
            185: cout.putstr("_+_+_+_+_+_+_+_+_+_+_+_+_+_+_+");
            186: switch_console(1);
            187: cout.putstr("in console 1 now\n");
            188: switch_console(0);
            189: cout.putstr("aaa");
            190: i++;
            191: }
            192:
            193: {
            194: /* 顏色測試 */
            195: /*
            196: BLACK, BLUE, GREEN, CYAN,
            197: RED, MAGENTA, BROWN, GRAY,
            198: DARKGRAY, LIGHTBLUE, LIGHTGREEN, LIGHTCYAN,
            199: LIGHTRED, LIGHTMAGENTA, YELLOW, WHITE
            200: */

            201: switch_console(0);
            202: cout.set_fg(GREEN);
            203: /* cout.set_fg(LIGHTBLUE); */
            204: /* cout.set_bg(GREEN); */
            205: cout.putstr("bad boy, y you goto here?\n");
            206: cout.putstr("sorry, sir, never again\n");
            207: i++;
            208: }
            209:
            210: {
            211: /* ostream類測試 */
            212: switch_console(0);
            213: cout << "hi, " << "Welcome use cout object.\n";
            214: extern unsigned int multiboot_magic;
            215: cout.flags(hex | showbase);
            216: multiboot_magic = 0x1BADB002;
            217: cout << "after boot, the magic is " << multiboot_magic << "\n";
            218: cout << "are you satisfaction with cout?\n";
            219: i++;
            220: }
            221: }
            222:
            223:

            上面代碼包含了測試用例,現在我們的c++ 內核也可以用cout 對象了,是不是很有成就感?

            Feedback

            # re: jinix內核虛擬控制臺實現(原創)  回復  更多評論   

            2007-07-12 10:54 by 天衣有縫
            修正了一個bug:
            cout << __func__ << endl;
            上面語句編譯不能通過,給出的提示似是而非,一番search得到的:
            static const char __func__[] = "function-name";

            解決方法是重載<<運算符以支持const char *的輸出:

            OStream& OStream::operator <<(const char *str)
            {
            putstr(str);
            return *this;
            }

            當然,putstr也要加const修飾:
            void TextIO::putstr(const char *s)
            {
            …………
            }

            # re: jinix內核虛擬控制臺實現(原創)  回復  更多評論   

            2007-07-15 12:39 by se
            學習
            国内精品久久久久影院免费| 狠狠88综合久久久久综合网| 精品久久综合1区2区3区激情| 久久久久国产一区二区| 亚洲国产成人精品女人久久久 | 国内高清久久久久久| 亚洲AV日韩AV天堂久久| 国产成人精品综合久久久| 国产精品久久久久久久人人看| 国产亚洲综合久久系列| 日日狠狠久久偷偷色综合免费| 色综合久久综合中文综合网| 久久国产一片免费观看| 久久国产精品99精品国产| 亚洲国产精品一区二区三区久久 | 久久综合狠狠综合久久激情 | 国产精品天天影视久久综合网| 久久综合狠狠综合久久97色| 久久精品国产亚洲AV无码偷窥| 久久强奷乱码老熟女| 99久久精品免费观看国产| 亚洲va久久久噜噜噜久久男同| 欧洲国产伦久久久久久久| 99热精品久久只有精品| 久久这里只精品国产99热| 久久精品国产亚洲av麻豆色欲| 久久国产AVJUST麻豆| 亚洲欧洲久久久精品| 久久天天躁狠狠躁夜夜2020| 国产免费久久精品99久久| 99久久国产亚洲高清观看2024 | 日韩精品国产自在久久现线拍| av无码久久久久久不卡网站| 久久香蕉超碰97国产精品| 97精品依人久久久大香线蕉97| 久久亚洲AV成人无码软件| 久久经典免费视频| 久久婷婷五月综合色奶水99啪| 国产精品久久新婚兰兰| 亚洲精品美女久久久久99| 久久亚洲日韩精品一区二区三区|