Nabootsing van Linus Torvalds: Skep u eie bedryfstelsel van nuuts af (II)

Welkom by nog 'n boodskap oor hoe om ons eie bedryfstelsel te skep, in hierdie geval NextDivel.

As ons teruggaan na die kode van die eerste pos aan die einde van alles moes ons met so iets vorendag gekom het:

Volgende Divel-1

As dit korrek is, kan ons voortgaan. Ek gaan die stelsel en struktuur wat ek op GitHub het, gebruik (http://github.com/AdrianArroyoCalle/next-divel) aangesien dit vir my en jou gemakliker is. Soos u kan sien, is die teks 'n basiese teks, dit is nie aantreklik nie. Dit lyk dalk soos iets ongewoon. Maar soos die spreekwoord sê, om kleure te proe, en in ons bedryfstelsel sal daar kleure wees. Die eerste kleure wat ons kan sit, is die wat die VGA-kaarte definieer, en dit is 0:

  1. Swart
  2. Azul
  3. Green
  4. Cyan
  5. Red
  6. Magenta
  7. bruin
  8. Ligte grys
  9. Donker grys
  10. Ligblou
  11. Ligte groen
  12. Siaan helder
  13. Ligrooi
  14. Ligte magenta
  15. Ligte bruin
  16. Blanco

Ons gaan hierdie kleure in 'n opskrif definieer om dit handiger te maak en miskien in die toekoms deel te word van die stelsel-API. So skep ons die lêer ND_Colors.hpp in die NextDivel-insluit.

#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

Terselfdertyd gaan ons nuwe funksies definieer om op die skerm gemakliker te skryf (nee, ons gaan nog nie printf implementeer nie, ek weet dat u dit wil hê). Ons sal 'n lêer en sy kop vir 'n stel skermverwante funksies (ND_Screen.cpp en ND_Screen.hpp) skep. Daarin gaan ons funksies skep om: die kleur van die letters en die agtergrond te verander, frases en letters te skryf, die skerm skoon te maak en op die skerm te beweeg. Ons gaan voort met die VGA-skerms, maar gebruik nou 'n paar bytes wat die kleur gee. ND_Screen.cpp lyk soos volg:

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

Die kop sal baie basies wees, so ek sluit dit nie hier in nie, maar beklemtoon die definisie van die ND_SIDE-tipe

typedef enum ND_SIDE{
ND_SIDE_BACKGROUND,
ND_SIDE_FOREGROUND
} ND_SIDE;

Noem ook dat ons die ND_Types.hpp-kop gebruik, hierdie kop definieer 'n paar basistipes vir uint8_t, uint16_t, ens. Gebaseer op char en int. Eintlik is hierdie opskrif die een in die C99-standaard en in werklikheid is my ND_Types.hpp 'n kopie / plak van die lêer vanaf Linux, sodat u dit kan uitruil en niks sal gebeur nie (daar is slegs definisies, geen funksies nie).

Om te toets of hierdie kode werk, gaan ons die C-invoerpunt van die kern verander:

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 as ons hierdie stappe volg, sal ons hierdie resultaat kry

Volgende Divel-3

Danksy hierdie funksies wat ons geskep het, kan ons klein GUI's maak, soos 'n kernpaniek wat ons elke keer sal sien as daar 'n onherstelbare fout is. Iets soos hierdie:

Volgende Divel-4

En hierdie klein GUI het ons net gemaak met hierdie funksies:

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 tot hier die boodskap. Ek herinner u aan die instruksies om die stelsel vanaf 0 saam te stel:

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 ek gebruik hierdie geleentheid om u te bedank vir die uitstekende ontvangs wat die eerste pos gehad het.


Die inhoud van die artikel voldoen aan ons beginsels van redaksionele etiek. Klik op om 'n fout te rapporteer hier.

5 kommentaar, los joune

Laat u kommentaar

Jou e-posadres sal nie gepubliseer word nie. Verpligte velde gemerk met *

*

*

  1. Verantwoordelik vir die data: Miguel Ángel Gatón
  2. Doel van die data: Beheer SPAM, bestuur van kommentaar.
  3. Wettiging: U toestemming
  4. Kommunikasie van die data: Die data sal nie aan derde partye oorgedra word nie, behalwe deur wettige verpligtinge.
  5. Datastoor: databasis aangebied deur Occentus Networks (EU)
  6. Regte: U kan u inligting te alle tye beperk, herstel en verwyder.

  1.   f3niX dijo

    Uitstekende vriend, selfs al maak ek my helm dood en verstaan ​​die kode in c ++.

    Groete.

  2.   pandacris dijo

    hierdie items is wonderlik. Hulle het my nuuskierigheid oor die lae-vlak prestasie van die verwerkers gewek.
    miskien as ek tyd het, sal ek met die volgende divel begin speel.
    Ek het lanklaas 'n artikel gestuur. reeds nodig

  3.   Jon hol dijo

    Goed, dit is die manier.

  4.   Miguel dijo

    Ek wou al lankal weet hoe om 'n bedryfstelsel te bou.

    Wag vir u volgende boodskap. Cheers

  5.   Julian dijo

    Groot vriend!
    Ek het net 'n probleem, kan iemand vir my 'n lêer in C van hierdie voorbeeld stuur?
    Dit stuur my altyd foute in die terminale