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:
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:
- Zwart
- Azul
- Planeet
- Cyaan
- Rojo
- Magenta
- Bruin
- Lichtgrijs
- Donkergrijs
- Licht blauw
- Lichtgroen
- Cyaan helder
- Licht rood
- Licht magenta
- Lichtbruin
- 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
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:
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.
Uitstekende vriend, toch vermoord ik mijn helm door de code in c ++ te begrijpen.
Groeten.
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
Goed, dat is de manier.
Ik heb lang willen weten hoe ik een besturingssysteem moet maken.
Wachten op je volgende bericht. Proost
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