Emulimi i Linus Torvalds: Krijoni sistemin tuaj operativ nga e para (II)

Mirësevini në një postim tjetër se si të krijoni sistemin tonë operativ, në këtë rast NextDivel.

Nëse kthehemi te kodi i postimi i parë në fund të gjithçkaje duhet të kemi dalë me diçka si kjo:

Devivel-1

Nëse kjo është e saktë, ne mund të vazhdojmë. Do të përdor sistemin dhe strukturën që kam në GitHub (http://github.com/AdrianArroyoCalle/next-divel) pasi është më komode për mua dhe për ju. Siç mund ta shihni teksti është një tekst bazë, nuk është tërheqës. Mund të duket si diçka e jashtëzakonshme. Por siç thuhet, për të shijuar ngjyrat, dhe në sistemin tonë operativ do të ketë ngjyra. Ngjyrat e para që do të jemi në gjendje të vendosim do të jenë ato që përcaktojnë kartat VGA dhe ato janë 0:

  1. I zi
  2. Azul
  3. E gjelbër
  4. Cyan
  5. Rojo
  6. I purpurtë
  7. Kafe
  8. Gri e hapur
  9. Gri e erret
  10. Blu e lehte
  11. Jeshile e hapur
  12. Cyan qartë
  13. Drite e kuqe
  14. Purpurtë e lehtë
  15. Kafe e lehtë
  16. Blanco

Ne do të përcaktojmë këto ngjyra në një kokë për ta pasur atë më të dobishëm dhe ndoshta në të ardhmen të bëhemi pjesë e sistemit API. Pra, ne krijojmë skedarin ND_Colors.hpp në përfshijnë NextDivel.

#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

Në të njëjtën kohë, ne do të përcaktojmë funksione të reja për të shkruar në ekran në një mënyrë më komode (jo, ne nuk do të zbatojmë printf akoma, e di që ju po e dëshironi atë). Ne do të krijojmë një skedar dhe titullin e tij për një sërë funksionesh të lidhura me ekranin (ND_Screen.cpp dhe ND_Screen.hpp). Në to do të krijojmë funksione për të: ndryshuar ngjyrën e shkronjave dhe sfondin, shkruajmë fjali dhe shkronja, pastrojmë ekranin dhe lëvizim nëpër ekran. Ne vazhdojmë të përdorim ekranet VGA por tani do të përdorim disa bajte që do t'i japin ngjyrën. ND_Screen.cpp do të dukej si:

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

Titulli do të jetë shumë themelor kështu që unë nuk e përfshij këtu, por theksoj përkufizimin e llojit ND_SIDE

typedef enum ND_SIDE{
ND_SIDE_BACKGROUND,
ND_SIDE_FOREGROUND
} ND_SIDE;

También mencionar que hacemos uso del header ND_Types.hpp, este header nos define unos tipos básicos para uint8_t, uint16_t, etc basado en los char y los int. Realmente este header es el en el estándar C99 y de hecho mi ND_Types.hpp es un copia/pega del archivo desde Linux, así que podeis intercambiarlos y no pasaría nada (solo hay definiciones, ninguna función).

Për të provuar nëse ky kod funksionon, ne do të modifikojmë pikën hyrëse C të bërthamës:

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

Dhe nëse ndjekim këto hapa do të merrnim këtë rezultat

Devivel-3

Falë këtyre funksioneve që kemi krijuar ne mund të fillojmë të bëjmë GUI të vegjël, siç është një panik i bërthamës që do të tregojmë sa herë që ka një gabim të pakthyeshëm. Diçka si kjo:

Devivel-4

Dhe këtë GUI të vogël ne e bëmë atë vetëm me këto funksione:

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

Dhe këtu postimi. Unë ju kujtoj udhëzimet për të përpiluar sistemin nga 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

Dhe përfitoj nga rasti t'ju falënderoj për pritjen e shkëlqyeshme që bëri postimi i parë.


Lini komentin tuaj

Adresa juaj e emailit nuk do të publikohet. Fusha e kërkuar janë shënuar me *

*

*

  1. Përgjegjës për të dhënat: Miguel Ángel Gatón
  2. Qëllimi i të dhënave: Kontrolloni SPAM, menaxhimin e komenteve.
  3. Legjitimimi: Pëlqimi juaj
  4. Komunikimi i të dhënave: Të dhënat nuk do t'u komunikohen palëve të treta përveç me detyrim ligjor.
  5. Ruajtja e të dhënave: Baza e të dhënave e organizuar nga Occentus Networks (BE)
  6. Të drejtat: Në çdo kohë mund të kufizoni, rikuperoni dhe fshini informacionin tuaj.

  1.   f3niX dijo

    Shok i shkëlqyeshëm, edhe pse po vras ​​helmetën time duke kuptuar kodin në c ++.

    Përshëndetje.

  2.   pandakrizë dijo

    keto artikuj jane te mrekullueshem. më kanë ngjallur edhe një herë kuriozitetin për performancën e nivelit të ulët të procesorëve.
    Ndoshta nëse kam kohë do të filloj të luaj me riparimin e ardhshëm.
    Unë nuk kam dërguar një artikull për një kohë të gjatë. tashmë e nevojshme

  3.   Jon gërmon dijo

    Mirë, kjo është rruga.

  4.   Miguel dijo

    Kam kohë që kam dashur të di se si të ndërtoj një sistem operativ.

    Në pritje të postimit tuaj të ardhshëm. Brohoritje

  5.   julian dijo

    Shok i madh!
    Unë thjesht kam një problem, a mund dikush të më kalojë një skedar C të këtij shembulli?
    Gjithmonë më dërgon gabime në terminal