Linus Torvalds utánzása: Készítse el saját operációs rendszerét a semmiből (II)

Üdvözöljük egy másik bejegyzésben arról, hogyan hozhatunk létre saját operációs rendszert, jelen esetben a NextDivel-t.

Ha visszatérünk a első bejegyzés mindennek végén valami ilyesmivel kellett volna előállnunk:

KövetkezőDivel-1

Ha ez helyes, folytathatjuk. A GitHub-on lévő rendszert és struktúrát fogom használnihttp://github.com/AdrianArroyoCalle/next-divel), mivel nekem és neked kényelmesebb. Amint láthatja, a szöveg alapszöveg, nem vonzó. Valami szokatlannak tűnhet. De ahogy a mondás tartja, a színek ízlelésére, és az operációs rendszerünkben lesznek színek. Az első olyan színek, amelyeket képesek leszünk elhelyezni, a VGA kártyákat definiálják, és ezek 0:

  1. Fekete
  2. Azul
  3. zöld
  4. Cián
  5. Rojo
  6. Bíborvörös
  7. barna
  8. Világos szürke
  9. Sötét szürke
  10. Világoskék
  11. Világos zöld
  12. Cián tiszta
  13. Halványpiros
  14. Világos bíborvörös
  15. Világos barna
  16. Blanco

Ezeket a színeket egy fejlécben fogjuk meghatározni, hogy könnyebben kezelhetőek legyenek, és a jövőben talán a rendszer API részévé váljanak. Így létrehozzuk az ND_Colors.hpp fájlt a NextDivel include-ban.

#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

Ugyanakkor új funkciókat fogunk meghatározni, amelyek kényelmesebb módon írhatók a képernyőre (nem, a printf-et még nem fogjuk megvalósítani, tudom, hogy te akarod). Létrehozunk egy fájlt és annak fejlécét a képernyőkhöz kapcsolódó funkciók számára (ND_Screen.cpp és ND_Screen.hpp). Ezekben olyan funkciókat fogunk létrehozni, amelyek: megváltoztatják a betűk és a háttér színét, mondatokat és betűket írnak, megtisztítják a képernyőt és mozognak a képernyőn. Folytatjuk a VGA képernyők használatát, de most néhány bájtot használunk, amelyek megadják a színt. Az ND_Screen.cpp a következőképpen néz ki:

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

A fejléc nagyon egyszerű lesz, ezért nem foglalom ide, de kiemelem az ND_SIDE típus definícióját

typedef enum ND_SIDE{
ND_SIDE_BACKGROUND,
ND_SIDE_FOREGROUND
} ND_SIDE;

Említse meg azt is, hogy az ND_Types.hpp fejlécet használjuk, ez a fejléc néhány alapvető típust határoz meg az uint8_t, uint16_t stb. számára char és int alapján. Valójában ez a fejléc a C99 szabványban található, és valójában az ND_Types.hpp a fájl másolása/beillesztése desde Linux, így kicserélheti őket, és semmi sem történne (csak definíciók vannak, funkciók nincsenek).

Annak teszteléséhez, hogy működik-e ez a kód, módosítani fogjuk a kernel C belépési pontját:

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

És ha ezeket a lépéseket követjük, akkor ezt az eredményt kapnánk

KövetkezőDivel-3

Ezeknek a létrehozott funkcióknak köszönhetően elkezdhetünk kis GUI-kat készíteni, például egy kernelpánikot, amelyet minden alkalommal megmutatunk, amikor helyrehozhatatlan hiba történik. Valami ilyesmi:

KövetkezőDivel-4

És ezt a kis grafikus felhasználói felületet csak a következő funkciókkal készítettük el:

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

És itt a bejegyzés. Emlékeztetem a rendszer 0-ból történő fordítására vonatkozó utasításokra:

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

És megragadom az alkalmat, hogy megköszönjem az első bejegyzés kiváló fogadtatását.


Hagyja megjegyzését

E-mail címed nem kerül nyilvánosságra. Kötelező mezők vannak jelölve *

*

*

  1. Az adatokért felelős: Miguel Ángel Gatón
  2. Az adatok célja: A SPAM ellenőrzése, a megjegyzések kezelése.
  3. Legitimáció: Az Ön beleegyezése
  4. Az adatok közlése: Az adatokat csak jogi kötelezettség alapján továbbítjuk harmadik felekkel.
  5. Adattárolás: Az Occentus Networks (EU) által üzemeltetett adatbázis
  6. Jogok: Bármikor korlátozhatja, helyreállíthatja és törölheti adatait.

  1.   f3niX dijo

    Kiváló barát, így is megölöm sisakomat, megértve a c ++ kódot.

    Üdvözlet.

  2.   pandacriss dijo

    ezek az elemek nagyszerűek. ismét felkeltették a kíváncsiságomat a processzorok alacsony szintű teljesítménye iránt.
    Talán, ha lesz időm, elkezdek játszani a következő divellel.
    Régóta nem küldtem cikket. már szükség van rá

  3.   - fúródik Jon dijo

    Rendben, ez a mód.

  4.   Miguel dijo

    Régóta szerettem volna tudni, hogyan lehet operációs rendszert készíteni.

    Várakozás a következő bejegyzésre. Egészségére

  5.   Giuliano dijo

    Nagyszerű barát!
    Csak egy problémám van, tud valaki átadni nekem egy C példát ennek a példának?
    Mindig hibákat küld nekem a terminálban