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

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

Jika kita kembali ke kode posting pertama di akhir segalanya kita seharusnya menghasilkan sesuatu seperti ini:

BerikutnyaDivel-1

Jika ini benar, kita bisa melanjutkan. Saya akan menggunakan sistem dan struktur yang saya miliki di GitHub (http://github.com/AdrianArroyoCalle/next-divel) karena lebih nyaman bagi saya dan Anda. Seperti yang Anda lihat, teks tersebut adalah teks dasar, itu tidak menarik. Ini mungkin tampak seperti sesuatu yang luar biasa. Tapi seperti kata pepatah, untuk mencicipi warna, dan di sistem operasi kita akan ada warna. Warna pertama yang dapat kita masukkan adalah warna yang menentukan kartu VGA dan 0:

  1. Hitam
  2. Azul
  3. Hijau
  4. Cyan
  5. Merah
  6. Magenta
  7. Coklat
  8. Abu-abu muda
  9. Abu-abu gelap
  10. Biru muda
  11. Hijau muda
  12. Cyan jernih
  13. Lampu merah
  14. Magenta muda
  15. Coklat muda
  16. Blanco

Kami akan menentukan warna-warna ini di header agar lebih praktis dan mungkin di masa mendatang menjadi bagian dari API sistem. Jadi kami membuat file ND_Colors.hpp di include NextDivel.

#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 saat yang sama, kami akan menentukan fungsi baru untuk ditulis di layar dengan cara yang lebih nyaman (tidak, kami belum akan menerapkan printf, saya tahu Anda bersedia). Kami akan membuat file dan headernya untuk serangkaian fungsi yang berhubungan dengan layar (ND_Screen.cpp dan ND_Screen.hpp). Di dalamnya kita akan membuat fungsi untuk: mengubah warna huruf dan latar belakang, menulis frasa dan huruf, membersihkan layar, dan bergerak di sekitar layar. Kami terus menggunakan layar VGA tetapi sekarang kami akan menggunakan beberapa byte yang akan memberi warna. ND_Screen.cpp akan terlihat seperti ini:

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

Headernya akan sangat mendasar jadi saya tidak memasukkannya di sini, tetapi menyoroti definisi tipe 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 kode ini berfungsi, kita akan memodifikasi titik masuk C dari 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 mendapatkan hasil ini

BerikutnyaDivel-3

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

BerikutnyaDivel-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 di sini posnya. Saya mengingatkan Anda tentang instruksi untuk mengkompilasi 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 menggunakan kesempatan ini untuk mengucapkan terima kasih atas penerimaan yang luar biasa dari postingan pertama.


tinggalkan Komentar Anda

Alamat email Anda tidak akan dipublikasikan. Bidang yang harus diisi ditandai dengan *

*

*

  1. Penanggung jawab data: Miguel Ángel Gatón
  2. Tujuan data: Mengontrol SPAM, manajemen komentar.
  3. Legitimasi: Persetujuan Anda
  4. Komunikasi data: Data tidak akan dikomunikasikan kepada pihak ketiga kecuali dengan kewajiban hukum.
  5. Penyimpanan data: Basis data dihosting oleh Occentus Networks (UE)
  6. Hak: Anda dapat membatasi, memulihkan, dan menghapus informasi Anda kapan saja.

  1.   f3niX dijo

    Sobat baik, meskipun begitu saya membunuh helm saya memahami kode di c ++.

    Salam.

  2.   krisis panda dijo

    barang-barang ini bagus. Mereka telah membangkitkan keingintahuan saya tentang kinerja prosesor tingkat rendah sekali lagi.
    mungkin jika saya punya waktu saya akan mulai bermain dengan divel berikutnya.
    Saya sudah lama tidak mengirim artikel. sudah dibutuhkan

  3.   Jon liang dijo

    Baiklah, begitulah.

  4.   miguel dijo

    Saya sudah lama ingin tahu bagaimana membangun sebuah sistem operasi.

    Menunggu posting Anda berikutnya. Bersulang

  5.   Giuliano dijo

    Teman baik!
    Saya hanya punya satu masalah, dapatkah seseorang memberikan saya file C dari contoh ini?
    Itu selalu mengirimi saya kesalahan di terminal