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:

Tahap-1 Seterusnya

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;

También mencionar que hacemos uso del header ND_Types.hpp, este header nos define unos tipos básicos para uint8_t, uint16_t, etc basado en los char y los int. Realmente este header es el en el estándar C99 y de hecho mi ND_Types.hpp es un copia/pega del archivo desde Linux, así que podeis intercambiarlos y no pasaría nada (solo hay definiciones, ninguna función).

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

Tahap-3 Seterusnya

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:

Tahap-4 Seterusnya

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.


5 komen, tinggalkan komen anda

Tinggalkan komen anda

Alamat email anda tidak akan disiarkan. Ruangan yang diperlukan ditanda dengan *

*

*

  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