Meniru Linus Torvalds: Buat sistem operasi anda sendiri dari awal (II)

Selamat datang di entri lain mengenai cara membuat sistem operasi kita sendiri, dalam hal ini NextDivel.

Sekiranya kita kembali ke kod jawatan pertama pada akhir semua yang sepatutnya kita buat seperti ini:

NextDivel-1

Sekiranya ini betul, kita boleh teruskan. Saya akan menggunakan sistem dan struktur yang saya ada di GitHub (http://github.com/AdrianArroyoCalle/next-divel) kerana ia lebih selesa untuk saya dan anda. Seperti yang anda lihat teks itu adalah teks asas, tidak menarik. Mungkin kelihatan seperti sesuatu yang tidak biasa. Tetapi seperti kata pepatah, untuk merasakan warna, dan dalam sistem operasi kita akan ada warna. Warna pertama yang akan dapat kita letakkan ialah warna yang menentukan kad VGA dan ia adalah 0:

  1. Hitam
  2. Azul
  3. Hijau
  4. Sian
  5. Merah
  6. Magenta
  7. Coklat
  8. Kelabu muda
  9. Kelabu gelap
  10. Biru muda
  11. Cahaya hijau
  12. Sian jelas
  13. Lampu merah
  14. Magenta ringan
  15. Coklat muda
  16. White

Kami akan menentukan warna-warna ini dalam tajuk untuk menjadikannya lebih berguna dan mungkin pada masa akan datang menjadi sebahagian daripada sistem API. Oleh itu, kami membuat fail ND_Colors.hpp di NextDivel termasuk.

#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

Pada masa yang sama kita akan menentukan fungsi baru untuk menulis di layar dengan cara yang lebih selesa (tidak, kita belum akan melaksanakan printf, saya tahu anda menginginkannya). Kami akan membuat fail dan tajuknya untuk sekumpulan fungsi yang berkaitan dengan skrin (ND_Screen.cpp dan ND_Screen.hpp). Di dalamnya kita akan membuat fungsi untuk: mengubah warna huruf dan latar belakang, menulis ayat dan huruf, membersihkan layar dan bergerak di sekitar layar. Kami terus menggunakan skrin VGA tetapi sekarang kami akan menggunakan beberapa bait yang akan memberi warna. ND_Screen.cpp akan kelihatan seperti:

/**
* @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;
}

Pengepala akan sangat asas jadi saya tidak memasukkannya di sini, tetapi sorot definisi jenis ND_SIDE

typedef enum ND_SIDE{
ND_SIDE_BACKGROUND,
ND_SIDE_FOREGROUND
} ND_SIDE;

Sebutkan juga bahawa kami menggunakan ND_Types.hpp header, header ini menentukan beberapa jenis asas untuk uint8_t, uint16_t, dll berdasarkan char dan int. Sebenarnya tajuk ini adalah yang ada dalam standard C99 dan sebenarnya ND_Types.hpp saya adalah salinan / tampal fail dari Linux, jadi anda boleh menukarnya dan tidak akan berlaku (hanya ada definisi, tidak ada fungsi).

Untuk menguji apakah kod ini berfungsi, kita akan mengubah titik masuk kernel:

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");

Dan jika kita mengikuti langkah-langkah ini, kita akan mendapat hasil ini

NextDivel-3

Berkat fungsi-fungsi ini yang telah kami buat, kami dapat mulai membuat GUI kecil, seperti kernel panik yang akan kami tunjukkan setiap kali ada kesalahan yang tidak dapat dipulihkan. Sesuatu seperti ini:

NextDivel-4

Dan GUI kecil ini kami buat hanya dengan fungsi berikut:

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);
}

Dan sampai di sini jawatan. Saya mengingatkan anda tentang arahan untuk menyusun sistem dari 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

Dan saya mengambil kesempatan ini untuk mengucapkan terima kasih atas penerimaan yang sangat baik dari siaran pertama.


Kandungan artikel mematuhi prinsip kami etika editorial. Untuk melaporkan ralat, klik di sini.

5 komen, tinggalkan komen anda

Tinggalkan komen anda

Alamat email anda tidak akan disiarkan.

*

*

  1. Bertanggungjawab atas data: Miguel Ángel Gatón
  2. Tujuan data: Mengendalikan SPAM, pengurusan komen.
  3. Perundangan: Persetujuan anda
  4. Komunikasi data: Data tidak akan disampaikan kepada pihak ketiga kecuali dengan kewajiban hukum.
  5. Penyimpanan data: Pangkalan data yang dihoskan oleh Occentus Networks (EU)
  6. Hak: Pada bila-bila masa anda boleh menghadkan, memulihkan dan menghapus maklumat anda.

  1.   F3niX kata

    Rakan yang baik, walaupun begitu saya menggunakan topi keledar saya memahami kod di c ++.

    Greetings.

  2.   pandacriss kata

    barang-barang ini hebat. mereka telah menimbulkan rasa ingin tahu saya mengenai prestasi pemproses tahap rendah sekali lagi.
    mungkin jika saya mempunyai masa saya akan mula bermain dengan permainan seterusnya.
    Sudah lama saya tidak menghantar artikel. sudah diperlukan

  3.   Jon menggali kata

    Baiklah, itulah caranya.

  4.   miguel kata

    Saya sudah lama ingin mengetahui bagaimana membina sistem operasi.

    Menunggu catatan anda yang seterusnya. salam

  5.   Giuliano kata

    Kawan terbaik!
    Saya hanya mempunyai satu masalah, bolehkah seseorang menyampaikan fail C contoh ini kepada saya?
    Ia selalu menghantar saya kesalahan di terminal

bool(benar)