Efterligne Linus Torvalds: Opret dit eget operativsystem fra bunden (II)

Velkommen til et andet indlæg om, hvordan vi opretter vores eget operativsystem, i dette tilfælde NextDivel.

Hvis vi går tilbage til koden for første indlæg i slutningen af ​​alt skulle vi have fundet på noget som dette:

NæsteDivel-1

Hvis dette er korrekt, kan vi fortsætte. Jeg vil bruge det system og den struktur, jeg har på GitHub (http://github.com/AdrianArroyoCalle/next-divel) da det er mere behageligt for mig og dig. Som du kan se, er teksten en grundtekst, den er ikke attraktiv. Det kan virke som noget ud over det sædvanlige. Men som man siger, at smage farver, og i vores operativsystem vil der være farver. De første farver, som vi skal kunne sætte, er dem, der definerer VGA-kortene, og de er 0:

  1. sort
  2. blå
  3. Verde
  4. Cyan
  5. rød
  6. Magenta
  7. brun
  8. Lysegrå
  9. Mørkegrå
  10. Lys blå
  11. Lysegrøn
  12. Cyan klar
  13. Lys rød
  14. Lys magenta
  15. Lysebrun
  16. hvid

Vi vil definere disse farver i en overskrift for at have det mere praktisk og måske i fremtiden blive en del af system-API'et. Så vi opretter filen ND_Colors.hpp i NextDivel inkluderer.

#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

Samtidig vil vi definere nye funktioner til at skrive på skærmen på en mere behagelig måde (nej, vi vil ikke implementere printf endnu, jeg ved, du vil have det). Vi opretter en fil og dens overskrift til et sæt skærmrelaterede funktioner (ND_Screen.cpp og ND_Screen.hpp). I dem opretter vi funktioner til: at ændre farven på bogstaverne og baggrunden, skrive sætninger og bogstaver, rense skærmen og flytte rundt på skærmen. Vi fortsætter med at bruge VGA-skærmene, men nu bruger vi et par byte, der giver farven. ND_Screen.cpp ser ud som:

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

Overskriften vil være meget grundlæggende, så jeg inkluderer det ikke her, men fremhæver definitionen af ​​ND_SIDE-typen

typedef enum ND_SIDE{
ND_SIDE_BACKGROUND,
ND_SIDE_FOREGROUND
} ND_SIDE;

Nævn også at vi bruger headeren ND_Types.hpp, denne header definerer nogle grundlæggende typer for uint8_t, uint16_t osv. baseret på char og int. Faktisk er denne header den i C99-standarden, og min ND_Types.hpp er faktisk en kopi/indsæt af filen desde Linux, så du kan udveksle dem og intet ville ske (der er kun definitioner, ingen funktioner).

For at teste om denne kode fungerer, skal vi ændre C-indgangspunktet for kernen:

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

Og hvis vi følger disse trin, ville vi få dette resultat

NæsteDivel-3

Takket være disse funktioner, som vi har oprettet, kan vi begynde at lave små GUI'er, såsom en kernepanik, som vi viser hver gang der er en uoprettelig fejl. Noget som dette:

NæsteDivel-4

Og denne lille GUI, vi lavede det kun med disse funktioner:

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

Og op til her indlægget. Jeg minder dig om instruktionerne til at kompilere systemet fra 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

Og jeg benytter lejligheden til at takke dig for den fremragende modtagelse, som det første indlæg havde.


Efterlad din kommentar

Din e-mailadresse vil ikke blive offentliggjort. Obligatoriske felter er markeret med *

*

*

  1. Ansvarlig for dataene: Miguel Ángel Gatón
  2. Formålet med dataene: Control SPAM, management af kommentarer.
  3. Legitimering: Dit samtykke
  4. Kommunikation af dataene: Dataene vil ikke blive kommunikeret til tredjemand, undtagen ved juridisk forpligtelse.
  5. Datalagring: Database hostet af Occentus Networks (EU)
  6. Rettigheder: Du kan til enhver tid begrænse, gendanne og slette dine oplysninger.

  1.   f3niX sagde han

    Fremragende ven, alligevel dræber jeg min hjelm, der forstår koden i c ++.

    Greetings.

  2.   pandacriss sagde han

    disse varer er gode. de har igen vakt min nysgerrighed over processorenes lave ydeevne.
    måske hvis jeg har tid, begynder jeg at spille med næste divel.
    Jeg har ikke sendt en artikel i lang tid. allerede nødvendigt

  3.   Jon burrows sagde han

    Okay, det er sådan.

  4.   miguel sagde han

    Jeg har længe ønsket at vide, hvordan man bygger et operativsystem.

    Venter på dit næste indlæg. Skål

  5.   Giuliano sagde han

    Stor ven!
    Jeg har bare et problem. Kan nogen sende mig en C-fil af dette eksempel?
    Det sender mig altid fejl i terminalen