Līnusa Torvalda atdarināšana: izveidojiet savu operētājsistēmu no jauna (II)

Laipni lūdzam citā ziņojumā par to, kā izveidot savu operētājsistēmu, šajā gadījumā NextDivel.

Ja mēs atgriezīsimies pie pirmais ziņojums visa beigās mums vajadzēja nākt klajā ar kaut ko līdzīgu šim:

NākamaisDivel-1

Ja tas ir pareizi, mēs varam turpināt. Es izmantošu sistēmu un struktūru, kas man ir vietnē GitHub (http://github.com/AdrianArroyoCalle/next-divel), jo tas ir ērtāk gan man, gan jums. Kā redzat, teksts ir pamata teksts, tas nav pievilcīgs. Tas var šķist kaut kas neparasts. Bet, kā teikts, pēc krāsas garšas, un mūsu operētājsistēmā krāsas būs. Pirmās krāsas, kuras mēs varēsim ievietot, būs tās, kas nosaka VGA kartes, un tās ir 0:

  1. Melns
  2. Azul
  3. Zaļš
  4. Ciāna
  5. Sarkans
  6. Fuksīns
  7. Brūns
  8. Gaiši pelēks
  9. Tumši pelēks
  10. Gaiši zils
  11. Gaiši zaļa
  12. Ciāna dzidra
  13. Gaiši sarkans
  14. Gaiši purpursarkana
  15. Gaiši brūns
  16. Blanco

Šīs krāsas mēs definēsim galvenē, lai tā būtu ērtāka un, iespējams, nākotnē kļūtu par sistēmas API daļu. Tātad mēs izveidojam failu ND_Colors.hpp NextDivel iekļaut.

#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

Tajā pašā laikā mēs definēsim jaunas funkcijas, lai ērtāk ierakstītu ekrānā (nē, mēs vēl neieviesīsim printf, es zinu, ka jūs to vēlaties). Mēs izveidosim failu un tā galveni ar ekrānu saistītu funkciju kopai (ND_Screen.cpp un ND_Screen.hpp). Tajos mēs izveidosim funkcijas: mainīt burtu un fona krāsu, rakstīt frāzes un burtus, notīrīt ekrānu un pārvietoties pa ekrānu. Mēs turpinām izmantot VGA ekrānus, bet tagad mēs izmantosim dažus baitus, kas piešķirs krāsu. ND_Screen.cpp izskatīsies šādi:

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

Galvene būs ļoti vienkārša, tāpēc es to šeit neiekļauju, bet izceļu ND_SIDE tipa definīciju

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).

Lai pārbaudītu, vai šis kods darbojas, mēs modificēsim kodola C ievadīšanas punktu:

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

Un, ja mēs izpildīsim šīs darbības, mēs iegūtu šo rezultātu

NākamaisDivel-3

Pateicoties šīm mūsu izveidotajām funkcijām, mēs varam sākt veidot mazus GUI, piemēram, kodola paniku, kuru mēs parādīsim katru reizi, kad rodas neatkopjama kļūda. Kaut kas tamlīdzīgs:

NākamaisDivel-4

Un šo mazo GUI mēs to izveidojām tikai ar šīm funkcijām:

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

Un līdz pat šai ziņai. Es jums atgādinu instrukcijas, lai sistēmu apkopotu no 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

Es izmantoju šo iespēju, lai pateiktos jums par izcilo uzņemšanu, kas bija pirmajā ierakstā.


Atstājiet savu komentāru

Jūsu e-pasta adrese netiks publicēta. Obligātie lauki ir atzīmēti ar *

*

*

  1. Atbildīgais par datiem: Migels Ángels Gatóns
  2. Datu mērķis: SPAM kontrole, komentāru pārvaldība.
  3. Legitimācija: jūsu piekrišana
  4. Datu paziņošana: Dati netiks paziņoti trešām personām, izņemot juridiskus pienākumus.
  5. Datu glabāšana: datu bāze, ko mitina Occentus Networks (ES)
  6. Tiesības: jebkurā laikā varat ierobežot, atjaunot un dzēst savu informāciju.

  1.   f3niX teica

    Izcils draugs, pat tāpēc es nogalinu savu ķiveri, saprotot kodu c ++.

    Sveicieni.

  2.   pandakriss teica

    šie priekšmeti ir lieliski. Viņi vēlreiz ir izraisījuši manu ziņkāri par procesoru zemo veiktspēju.
    varbūt, ja man būs laiks, es sākšu spēlēt ar next-divel.
    Sen neesmu sūtījis rakstu. tas ir nepieciešams

  3.   Džons ierok teica

    Labi, tas ir veids.

  4.   Miguel teica

    Es jau sen gribēju zināt, kā izveidot operētājsistēmu.

    Gaidu nākamo ierakstu. Priekā

  5.   Giuliano teica

    Lielisks draugs!
    Man vienkārši ir viena problēma, vai kāds var man nodot šī piemēra C failu?
    Tas man vienmēr nosūta kļūdas terminālā