Linus Torvalds emulieren: Erstellen Sie Ihr eigenes Betriebssystem von Grund auf neu (II)

Willkommen zu einem weiteren Beitrag zum Erstellen unseres eigenen Betriebssystems, in diesem Fall NextDivel.

Wenn wir zum Code des zurückkehren Erster Beitrag am ende von allem hätten wir uns so etwas einfallen lassen sollen:

NächsterDive-1

Wenn dies korrekt ist, können wir fortfahren. Ich werde das System und die Struktur verwenden, die ich auf GitHub habe (http://github.com/AdrianArroyoCalle/next-divel) wie es für mich und dich angenehmer ist. Wie Sie sehen können, handelt es sich bei dem Text um einen Basistext, der jedoch nicht attraktiv ist. Es mag wie etwas Außergewöhnliches erscheinen. Aber wie das Sprichwort sagt, um Farben zu schmecken, und in unserem Betriebssystem wird es Farben geben. Die ersten Farben, die wir setzen können, sind diejenigen, die die VGA-Karten definieren, und sie sind 0:

  1. schwarz
  2. blau
  3. grün
  4. Cyan
  5. rot
  6. Magenta
  7. braun
  8. hellgrau
  9. Dunkelgrau
  10. Hellblau
  11. Hellgrün
  12. Cyan klar
  13. Hellrot
  14. Helles Magenta
  15. Hellbraun
  16. Blanco

Wir werden diese Farben in einem Header definieren, um sie praktischer zu gestalten und möglicherweise in Zukunft Teil der System-API zu werden. Also erstellen wir die Datei ND_Colors.hpp im 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

Gleichzeitig werden wir neue Funktionen definieren, um komfortabler auf den Bildschirm zu schreiben (nein, wir werden printf noch nicht implementieren, ich weiß, dass Sie dazu bereit sind). Wir werden eine Datei und ihren Header für eine Reihe von bildschirmbezogenen Funktionen erstellen (ND_Screen.cpp und ND_Screen.hpp). In ihnen werden wir Funktionen erstellen, um: die Farbe der Buchstaben und des Hintergrunds zu ändern, Phrasen und Buchstaben zu schreiben, den Bildschirm zu reinigen und sich auf dem Bildschirm zu bewegen. Wir verwenden weiterhin die VGA-Bildschirme, aber jetzt werden wir einige Bytes verwenden, die die Farbe ergeben. ND_Screen.cpp würde folgendermaßen aussehen:

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

Der Header ist sehr einfach, daher füge ich ihn hier nicht ein, sondern hebe die Definition des ND_SIDE-Typs hervor

typedef enum ND_SIDE{
ND_SIDE_BACKGROUND,
ND_SIDE_FOREGROUND
} ND_SIDE;

Erwähnen Sie auch, dass wir den Header ND_Types.hpp verwenden. Dieser Header definiert einige Grundtypen für uint8_t, uint16_t usw. basierend auf char und int. Eigentlich ist dieser Header der im C99-Standard und tatsächlich ist mein ND_Types.hpp ein Kopieren/Einfügen der Datei desde Linux, sodass Sie sie austauschen können und nichts passieren würde (es gibt nur Definitionen, keine Funktionen).

Um zu testen, ob dieser Code funktioniert, ändern wir den C-Einstiegspunkt des Kernels:

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

Und wenn wir diese Schritte befolgen, erhalten wir dieses Ergebnis

NächsterDive-3

Dank dieser von uns erstellten Funktionen können wir kleine GUIs erstellen, z. B. eine Kernel-Panik, die jedes Mal angezeigt wird, wenn ein nicht behebbarer Fehler auftritt. Etwas wie das:

NächsterDive-4

Und diese kleine GUI haben wir nur mit folgenden Funktionen gemacht:

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

Und bis hierher die Post. Ich erinnere Sie an die Anweisungen zum Kompilieren des Systems von 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

Und ich nutze diese Gelegenheit, um Ihnen für den hervorragenden Empfang zu danken, den der erste Beitrag hatte.


Hinterlasse einen Kommentar

Ihre E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind markiert mit *

*

*

  1. Verantwortlich für die Daten: Miguel Ángel Gatón
  2. Zweck der Daten: Kontrolle von SPAM, Kommentarverwaltung.
  3. Legitimation: Ihre Zustimmung
  4. Übermittlung der Daten: Die Daten werden nur durch gesetzliche Verpflichtung an Dritte weitergegeben.
  5. Datenspeicherung: Von Occentus Networks (EU) gehostete Datenbank
  6. Rechte: Sie können Ihre Informationen jederzeit einschränken, wiederherstellen und löschen.

  1.   f3niX sagte

    Ausgezeichneter Freund, trotzdem töte ich meinen Helm und verstehe den Code in C ++.

    Grüße.

  2.   Pandacriss sagte

    Diese Artikel sind großartig. Sie haben meine Neugier auf die geringe Leistung der Prozessoren erneut geweckt.
    Wenn ich Zeit habe, fange ich vielleicht an, mit Next-Divel zu spielen.
    Ich habe lange keinen Artikel mehr verschickt. schon gebraucht

  3.   Jon gräbt sagte

    Gut, das ist der Weg.

  4.   Miguel sagte

    Ich wollte schon lange wissen, wie man ein Betriebssystem erstellt.

    Warten auf Ihren nächsten Beitrag. Prost

  5.   julianisch sagte

    Toller Freund!
    Ich habe nur ein Problem. Kann mir jemand eine C-Datei dieses Beispiels übergeben?
    Es sendet mir immer Fehler im Terminal