Lino Torvaldso mėgdžiojimas: sukurkite savo operacinę sistemą nuo nulio (II)

Sveiki atvykę į kitą įrašą apie tai, kaip sukurti savo operacinę sistemą, šiuo atveju „NextDivel“.

Jei grįšime prie pirmasis įrašas visko pabaigoje turėjome sugalvoti kažką panašaus:

„NextDivel-1“

Jei tai teisinga, galime tęsti. Aš naudosiu sistemą ir struktūrą, kurią turiu „GitHub“ (http://github.com/AdrianArroyoCalle/next-divel), nes man ir jums patogiau. Kaip matote, tekstas yra pagrindinis tekstas, jis nėra patrauklus. Tai gali atrodyti kažkas neįprasto. Bet, kaip sakoma, paragauti spalvų, o mūsų operacinėje sistemoje bus spalvų. Pirmosios spalvos, kurias galėsime įdėti, bus tos, kurios apibrėžia VGA korteles, ir jos yra 0:

  1. negras
  2. Azul
  3. Žalias
  4. Žalsvai
  5. Raudonas
  6. Magenta
  7. Ruda
  8. Šviesiai pilka
  9. Tamsiai pilka
  10. Šviesiai mėlyna
  11. Šviesiai žalia
  12. Žalsvai žydra
  13. Šviesiai raudona
  14. Šviesiai purpurinė
  15. Šviesiai ruda
  16. Blanco

Mes apibrėžsime šias spalvas antraštėje, kad jos būtų patogesnės ir galbūt ateityje taptų sistemos API dalimi. Taigi mes sukuriame failą ND_Colors.hpp „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

Tuo pačiu metu nustatysime naujas funkcijas, kad būtų patogiau rašyti ekrane (ne, mes dar nesiimame diegti „printf“, žinau, kad jūs to norite). Sukursime failą ir jo antraštę, skirtą su ekranu susijusių funkcijų rinkiniui (ND_Screen.cpp ir ND_Screen.hpp). Jose mes sukursime funkcijas: pakeisti raidžių ir fono spalvą, rašyti frazes ir raides, išvalyti ekraną ir judėti ekrane. Mes ir toliau naudojame VGA ekranus, bet dabar mes naudosime keletą baitų, kurie suteiks spalvą. „ND_Screen.cpp“ atrodytų taip:

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

Antraštė bus labai paprasta, todėl jos čia neįtraukiu, bet paryškinu ND_SIDE tipo apibrėžimą

typedef enum ND_SIDE{
ND_SIDE_BACKGROUND,
ND_SIDE_FOREGROUND
} ND_SIDE;

Taip pat paminėkite, kad naudojame antraštę ND_Types.hpp. Ši antraštė apibrėžia kai kuriuos pagrindinius uint8_t, uint16_t ir tt tipus, remiantis char ir int. Tiesą sakant, ši antraštė yra C99 standarto antraštė, o iš tikrųjų mano ND_Types.hpp yra failo kopija / įklijavimas desde Linux, todėl galima jas pasikeisti ir nieko neatsitiktų (yra tik apibrėžimai, jokių funkcijų).

Norėdami patikrinti, ar šis kodas veikia, pakeisime branduolio C įėjimo tašką:

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

Ir jei atliksime šiuos veiksmus, gautume šį rezultatą

„NextDivel-3“

Dėl šių mūsų sukurtų funkcijų galime pradėti kurti mažas GUI, tokias kaip branduolio panika, kurią parodysime kiekvieną kartą, kai yra neatkuriama klaida. Kažkas panašaus į tai:

„NextDivel-4“

Šį mažą GUI sukūrėme tik naudodamiesi šiomis funkcijomis:

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

Ir štai įrašas. Primenu instrukcijas, kaip sukompiliuoti sistemą iš 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

Naudodamasis proga padėkoju jums už puikų priėmimą, kurį sulaukė pirmasis pranešimas.


Palikite komentarą

Jūsų elektroninio pašto adresas nebus skelbiamas. Privalomi laukai yra pažymėti *

*

*

  1. Atsakingas už duomenis: Miguel Ángel Gatón
  2. Duomenų paskirtis: kontroliuoti šlamštą, komentarų valdymą.
  3. Įteisinimas: jūsų sutikimas
  4. Duomenų perdavimas: Duomenys nebus perduoti trečiosioms šalims, išskyrus teisinius įsipareigojimus.
  5. Duomenų saugojimas: „Occentus Networks“ (ES) talpinama duomenų bazė
  6. Teisės: bet kuriuo metu galite apriboti, atkurti ir ištrinti savo informaciją.

  1.   f3niX sakė

    Puikus draugas, net todėl žudau šalmą, suprasdamas kodą c ++.

    Sveikinimai.

  2.   pandakrisas sakė

    šie daiktai yra puikūs. Jie dar kartą sukėlė mano smalsumą dėl žemo lygio procesorių našumo.
    gal jei turėsiu laiko, pradėsiu groti su „next-divel“.
    Jau seniai nesiunčiau straipsnio. jau reikia

  3.   Jonas iškasa sakė

    Gerai, taip yra.

  4.   miguel sakė

    Aš jau seniai norėjau žinoti, kaip sukurti operacinę sistemą.

    Laukiu kito įrašo. Cheers

  5.   Džulianas sakė

    Puikus draugas!
    Aš tiesiog turiu problemų, ar kas nors gali perduoti man šio pavyzdžio C failą?
    Tai visada siunčia man klaidas terminale