Mô phỏng Linus Torvalds: Tạo hệ điều hành của riêng bạn từ đầu (II)

Chào mừng bạn đến với một bài đăng khác về cách tạo hệ điều hành của riêng chúng tôi, trong trường hợp này là NextDivel.

Nếu chúng ta quay lại mã của bài đăng đầu tiên ở phần cuối của mọi thứ chúng ta nên nghĩ ra một cái gì đó như thế này:

Cấp độ tiếp theo-1

Nếu điều này là chính xác, chúng tôi có thể tiếp tục. Tôi sẽ sử dụng hệ thống và cấu trúc mà tôi có trên GitHub (http://github.com/AdrianArroyoCalle/next-divel) vì nó thoải mái hơn cho tôi và bạn. Như bạn có thể thấy văn bản là một văn bản cơ bản, nó không hấp dẫn. Nó có vẻ giống như một cái gì đó khác thường. Nhưng như người ta vẫn nói, để nếm màu sắc, và trong hệ điều hành của chúng ta sẽ có màu sắc. Các màu đầu tiên mà chúng ta có thể đặt sẽ là những màu xác định card VGA và chúng là 0:

  1. Đen
  2. Azul
  3. Verde
  4. Cyan
  5. Rojo
  6. Magenta
  7. Marrón
  8. Xám nhạt
  9. Màu xám đen
  10. Màu xanh nhạt
  11. Màu xanh lợt
  12. Lục lam rõ ràng
  13. Đỏ nhạt
  14. Màu đỏ tươi sáng
  15. Nâu nhạt
  16. Blanco

Chúng tôi sẽ xác định các màu này trong tiêu đề để nó tiện dụng hơn và có lẽ trong tương lai sẽ trở thành một phần của API hệ thống. Vì vậy, chúng tôi tạo tệp ND_Colors.hpp trong NextDivel bao gồm.

#ifndef ND_COLOR_HPP
#define ND_COLOR_HPP
typedef enum ND_Color{
ND_COLOR_BLACK = 0,
ND_COLOR_BLUE = 1,
ND_COLOR_GREEN = 2,
ND_COLOR_CYAN = 3,
ND_COLOR_RED = 4,
ND_COLOR_MAGENTA = 5,
ND_COLOR_BROWN = 6,
ND_COLOR_LIGHT_GREY = 7,
ND_COLOR_DARK_GREY = 8,
ND_COLOR_LIGHT_BLUE = 9,
ND_COLOR_LIGHT_GREEN = 10,
ND_COLOR_LIGHT_CYAN = 11,
ND_COLOR_LIGHT_RED = 12,
ND_COLOR_LIGHT_MAGENTA = 13,
ND_COLOR_LIGHT_BROWN = 14,
ND_COLOR_WHITE = 15
} ND_Color;
#endif

Đồng thời, chúng tôi sẽ xác định các hàm mới để viết trên màn hình theo cách thoải mái hơn (không, chúng tôi sẽ chưa triển khai printf, tôi biết bạn đang muốn nó). Chúng tôi sẽ tạo một tệp và tiêu đề của tệp cho một tập hợp các chức năng liên quan đến màn hình (ND_Screen.cpp và ND_Screen.hpp). Trong chúng, chúng ta sẽ tạo các chức năng để: thay đổi màu sắc của chữ cái và nền, viết câu và chữ cái, làm sạch màn hình và di chuyển xung quanh màn hình. Chúng tôi tiếp tục sử dụng màn hình VGA nhưng bây giờ chúng tôi sẽ sử dụng một vài byte sẽ cho màu sắc. ND_Screen.cpp sẽ giống như sau:

/**
* @file ND_Screen.cpp
* @author Adrián Arroyo Calle
* @brief Implements four easy functions for write strings directly
*/
#include <ND_Types.hpp>
#include <ND_Color.hpp>
#include <ND_Screen.hpp>
uint16_t *vidmem= (uint16_t *)0xB8000;
ND_Color backColour = ND_COLOR_BLACK;
ND_Color foreColour = ND_COLOR_WHITE;
uint8_t cursor_x = 0;
uint8_t cursor_y = 0;
/**
* @brief Gets the current color
* @param side The side to get the color
* */
ND_Color ND::Screen::GetColor(ND_SIDE side)
{
if(side==ND_SIDE_BACKGROUND){
return backColour;
}else{
return foreColour;
}
}
/**
* @brief Sets the color to a screen side
* @param side The side to set colour
* @param colour The new colour
* @see GetColor
* */
void ND::Screen::SetColor(ND_SIDE side, ND_Color colour)
{
if(side==ND_SIDE_BACKGROUND)
{
backColour=colour;
}else{
foreColour=colour;
}
}
/**
* @brief Puts the char on screen
* @param c The character to write
* */
void ND::Screen::PutChar(char c)
{
uint8_t attributeByte = (backColour << 4) | (foreColour & 0x0F);
uint16_t attribute = attributeByte << 8; uint16_t *location; if (c == 0x08 && cursor_x) { cursor_x--; }else if(c == '\r') { cursor_x=0; }else if(c == '\n') { cursor_x=0; cursor_y=1; } if(c >= ' ') /* Printable character */
{
location = vidmem + (cursor_y*80 + cursor_x);
*location = c | attribute;
cursor_x++;
}
if(cursor_x >= 80) /* New line, please*/
{
cursor_x = 0;
cursor_y++;
}
/* Scroll if needed*/
uint8_t attributeByte2 = (0 /*black*/ << 4) | (15 /*white*/ & 0x0F);
uint16_t blank = 0x20 /* space */ | (attributeByte2 << 8); if(cursor_y >= 25)
{
int i;
for (i = 0*80; i < 24*80; i++)
{
vidmem[i] = vidmem[i+80];
}
// The last line should now be blank. Do this by writing
// 80 spaces to it.
for (i = 24*80; i < 25*80; i++)
{
vidmem[i] = blank;
}
// The cursor should now be on the last line.
cursor_y = 24;
}
}
/**
* @brief Puts a complete string to screen
* @param str The string to write
* */
void ND::Screen::PutString(const char* str)
{
int i=0;
while(str[i])
{
ND::Screen::PutChar(str[i++]);
}
}
/**
* @brief Cleans the screen with a color
* @param colour The colour to fill the screen
* */
void ND::Screen::Clear(ND_Color colour)
{
uint8_t attributeByte = (colour /*background*/ << 4) | (15 /*white - foreground*/ & 0x0F);
uint16_t blank = 0x20 /* space */ | (attributeByte << 8);
int i;
for (i = 0; i < 80*25; i++)
{
vidmem[i] = blank;
}
cursor_x = 0;
cursor_y = 0;
}
/**
* @brief Sets the cursor via software
* @param x The position of X
* @param y The position of y
* */
void ND::Screen::SetCursor(uint8_t x, uint8_t y)
{
cursor_x=x;
cursor_y=y;
}

Tiêu đề sẽ rất cơ bản nên tôi không đưa nó vào đây, nhưng làm nổi bật định nghĩa của loại ND_SIDE

typedef enum ND_SIDE{
ND_SIDE_BACKGROUND,
ND_SIDE_FOREGROUND
} ND_SIDE;

Cũng đề cập rằng chúng tôi sử dụng tiêu đề ND_Types.hpp, tiêu đề này xác định một số loại cơ bản cho uint8_t, uint16_t, v.v. dựa trên char và int. Trên thực tế, tiêu đề này là tiêu đề trong tiêu chuẩn C99 và trên thực tế, ND_Types.hpp của tôi là bản sao/dán tệp desde Linux, vì vậy bạn có thể trao đổi chúng và sẽ không có gì xảy ra (chỉ có định nghĩa, không có chức năng).

Để kiểm tra xem mã này có hoạt động hay không, chúng ta sẽ sửa đổi điểm vào C của hạt nhân:

ND::Screen::Clear(ND_COLOR_WHITE);
ND::Screen::SetColor(ND_SIDE_BACKGROUND,ND_COLOR_WHITE);
ND::Screen::SetColor(ND_SIDE_FOREGROUND,ND_COLOR_GREEN);
ND::Screen::PutString("NextDivel\n");
ND::Screen::SetColor(ND_SIDE_FOREGROUND,ND_COLOR_BLACK);
ND::Screen::PutString("Licensed under GNU GPL v2");

Và nếu chúng ta làm theo các bước này, chúng ta sẽ nhận được kết quả này

Cấp độ tiếp theo-3

Nhờ các chức năng mà chúng tôi đã tạo này, chúng tôi có thể bắt đầu tạo các GUI nhỏ, chẳng hạn như sự hoảng sợ của nhân mà chúng tôi sẽ hiển thị mỗi khi có lỗi không thể khôi phục. Một cái gì đó như thế này:

Cấp độ tiếp theo-4

Và GUI nhỏ này, chúng tôi đã tạo ra nó chỉ với các chức năng sau:

void ND::Panic::Show(const char* error)
{
ND::Screen::Clear(ND_COLOR_RED);
ND::Screen::SetColor(ND_SIDE_BACKGROUND, ND_COLOR_WHITE);
ND::Screen::SetColor(ND_SIDE_FOREGROUND, ND_COLOR_RED);
ND::Screen::SetCursor(29,10); //(80-22)/2
ND::Screen::PutString("NextDivel Kernel Error\n");
ND::Screen::SetCursor(15,12);
ND::Screen::PutString(error);
}

Và đến đây bài đăng. Tôi nhắc bạn về các hướng dẫn để biên dịch hệ thống từ 0:

git clone http://github.com/AdrianArroyoCalle/next-divel
cd next-divel
mkdir build && cd build
cmake ..
make
make DESTDIR=next install
chmod +x iso.sh
./iso.sh
qemu-system-i386 nextdivel.iso

Và tôi nhân cơ hội này để cảm ơn bạn vì sự đón nhận tuyệt vời mà bài viết đầu tiên đã có.


Để lại bình luận của bạn

địa chỉ email của bạn sẽ không được công bố. Các trường bắt buộc được đánh dấu bằng *

*

*

  1. Chịu trách nhiệm về dữ liệu: Miguel Ángel Gatón
  2. Mục đích của dữ liệu: Kiểm soát SPAM, quản lý bình luận.
  3. Hợp pháp: Sự đồng ý của bạn
  4. Truyền thông dữ liệu: Dữ liệu sẽ không được thông báo cho các bên thứ ba trừ khi có nghĩa vụ pháp lý.
  5. Lưu trữ dữ liệu: Cơ sở dữ liệu do Occentus Networks (EU) lưu trữ
  6. Quyền: Bất cứ lúc nào bạn có thể giới hạn, khôi phục và xóa thông tin của mình.

  1.   f3niX dijo

    Người bạn tuyệt vời, ngay cả khi tôi đang giết chiếc mũ bảo hiểm của mình khi hiểu mã trong c ++.

    Chúc mừng.

  2.   gấu trúc dijo

    những mặt hàng này là tuyệt vời. họ đã khơi gợi sự tò mò của tôi về hiệu suất cấp thấp của bộ xử lý một lần nữa.
    có lẽ nếu có thời gian tôi sẽ bắt đầu chơi với next-divel.
    Tôi đã không gửi một bài báo trong một thời gian dài. đã cần thiết

  3.   Jon đào hang dijo

    Được rồi, đó là cách.

  4.   miguel dijo

    Từ lâu tôi đã muốn biết cách xây dựng một hệ điều hành.

    Chờ đợi bài viết tiếp theo của bạn. Chúc mừng

  5.   Giuliano dijo

    Bạn tốt!
    Tôi chỉ có một vấn đề, ai đó có thể chuyển cho tôi một tệp C của ví dụ này được không?
    Nó luôn gửi cho tôi lỗi trong thiết bị đầu cuối