Linus Torvalds emuleren: maak uw eigen besturingssysteem vanaf nul (II)

Welkom bij een ander bericht over het maken van ons eigen besturingssysteem, in dit geval NextDivel.

Als we teruggaan naar de code van het eerste bericht aan het einde van alles hadden we zoiets als dit moeten bedenken:

Volgende Duik-1

Als dit klopt, kunnen we doorgaan. Ik ga het systeem en de structuur gebruiken die ik op GitHub heb (http://github.com/AdrianArroyoCalle/next-divel) omdat het comfortabeler is voor mij en voor jou. Zoals u kunt zien, is de tekst een basistekst, deze is niet aantrekkelijk. Het lijkt misschien iets bijzonders. Maar zoals het gezegde luidt, kleuren proeven, en in ons besturingssysteem zullen er kleuren zijn. De eerste kleuren die we kunnen gebruiken, zijn de kleuren die de VGA-kaarten definiëren en dat zijn er 0:

  1. Zwart
  2. Azul
  3. Planeet
  4. Cyaan
  5. Rojo
  6. Magenta
  7. Bruin
  8. Lichtgrijs
  9. Donkergrijs
  10. Licht blauw
  11. Lichtgroen
  12. Cyaan helder
  13. Licht rood
  14. Licht magenta
  15. Lichtbruin
  16. Blanco

We gaan deze kleuren in een koptekst definiëren om het handiger te hebben en misschien in de toekomst onderdeel te worden van de systeem-API. Dus maken we het bestand ND_Colors.hpp in de NextDivel include.

#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

Tegelijkertijd gaan we nieuwe functies definiëren om op een comfortabelere manier op het scherm te schrijven (nee, we gaan printf nog niet implementeren, ik weet dat je het wilt). We zullen een bestand en de koptekst maken voor een reeks schermgerelateerde functies (ND_Screen.cpp en ND_Screen.hpp). Daarin zullen we functies creëren om: de kleur van de letters en de achtergrond te veranderen, zinnen en letters te schrijven, het scherm schoon te maken en over het scherm te bewegen. We blijven de VGA-schermen gebruiken, maar nu gebruiken we een paar bytes die de kleur zullen geven. ND_Screen.cpp zou er als volgt uitzien:

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

De koptekst zal erg basic zijn, dus ik neem hem hier niet op, maar benadruk de definitie van het ND_SIDE-type

typedef enum ND_SIDE{
ND_SIDE_BACKGROUND,
ND_SIDE_FOREGROUND
} ND_SIDE;

Vermeld ook dat we de header ND_Types.hpp gebruiken, deze header definieert enkele basistypen voor uint8_t, uint16_t, enz. op basis van char en int. Eigenlijk is deze header degene in de C99-standaard en in feite is mijn ND_Types.hpp een kopieer/plak van het bestand desde Linux, dus je kunt ze uitwisselen en er gebeurt niets (er zijn alleen definities, geen functies).

Om te testen of deze code werkt, gaan we het C-ingangspunt van de kernel wijzigen:

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

En als we deze stappen volgen, krijgen we dit resultaat

Volgende Duik-3

Dankzij deze functies die we hebben gemaakt, kunnen we beginnen met het maken van kleine GUI's, zoals een kernel panic die we elke keer laten zien als er een onherstelbare fout is. Iets zoals dit:

Volgende Duik-4

En deze kleine GUI hebben we alleen gemaakt met deze functies:

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

En hier de post. Ik herinner je aan de instructies om het systeem uit 0 te compileren:

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

En ik maak van de gelegenheid gebruik om u te bedanken voor de uitstekende ontvangst die de eerste post heeft gehad.


Laat je reactie achter

Uw e-mailadres wordt niet gepubliceerd. Verplichte velden zijn gemarkeerd met *

*

*

  1. Verantwoordelijk voor de gegevens: Miguel Ángel Gatón
  2. Doel van de gegevens: Controle SPAM, commentaarbeheer.
  3. Legitimatie: uw toestemming
  4. Mededeling van de gegevens: De gegevens worden niet aan derden meegedeeld, behalve op grond van wettelijke verplichting.
  5. Gegevensopslag: database gehost door Occentus Networks (EU)
  6. Rechten: u kunt uw gegevens op elk moment beperken, herstellen en verwijderen.

  1.   f3niX zei

    Uitstekende vriend, toch vermoord ik mijn helm door de code in c ++ te begrijpen.

    Groeten.

  2.   pandakris zei

    deze items zijn geweldig. Ze hebben mijn nieuwsgierigheid naar de lage prestaties van de processors opnieuw gewekt.
    Als ik tijd heb, ga ik misschien spelen met next-divel.
    Ik heb al een lange tijd geen artikel verzonden. al nodig

  3.   Jon graaft zich in zei

    Goed, dat is de manier.

  4.   miguel zei

    Ik heb lang willen weten hoe ik een besturingssysteem moet maken.

    Wachten op je volgende bericht. Proost

  5.   Giuliano zei

    Goede vriend!
    Ik heb gewoon een probleem, kan iemand mij een bestand in C van dit voorbeeld geven?
    Het stuurt me altijd fouten in de terminal