Προσομοίωση Linus Torvalds: Δημιουργήστε το δικό σας λειτουργικό σύστημα από το μηδέν (II)

Καλώς ήλθατε σε μια άλλη ανάρτηση σχετικά με τον τρόπο δημιουργίας του δικού μας λειτουργικού συστήματος, σε αυτήν την περίπτωση NextDivel.

Εάν επιστρέψουμε στον κώδικα του πρώτη θέση στο τέλος όλων όσων έπρεπε να έχουμε καταλήξει σε κάτι τέτοιο:

Επόμενο Επίπεδο-1

Εάν αυτό είναι σωστό, μπορούμε να συνεχίσουμε. Θα χρησιμοποιήσω το σύστημα και τη δομή που έχω στο GitHub (http://github.com/AdrianArroyoCalle/next-divel) καθώς είναι πιο άνετο για μένα και εσένα. Όπως μπορείτε να δείτε ότι το κείμενο είναι ένα βασικό κείμενο, δεν είναι ελκυστικό. Μπορεί να φαίνεται κάτι ασυνήθιστο. Αλλά όπως λέει και η παροιμία, για να δοκιμάσετε χρώματα, και στο λειτουργικό μας σύστημα θα υπάρχουν χρώματα. Τα πρώτα χρώματα που θα μπορέσουμε να βάλουμε θα είναι εκείνα που ορίζουν τις κάρτες VGA και είναι 0:

  1. Μαύρος
  2. Azul
  3. Πράσινος
  4. Κυανό
  5. Κόκκινος
  6. Ματζέντα
  7. καφέ
  8. Ανοιχτό γκρι
  9. Σκούρο γκρίζο
  10. Ανοιχτό μπλε
  11. Ανοιχτό πράσινο
  12. Κυανό καθαρό
  13. Ανοιχτό κόκκινο
  14. Φως ματζέντα
  15. Ανοιχτό καφέ
  16. Μπλάνκο

Θα ορίσουμε αυτά τα χρώματα σε μια κεφαλίδα για να είναι πιο εύχρηστα και ίσως στο μέλλον να γίνουν μέρος του API συστήματος. Έτσι δημιουργούμε το αρχείο 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

Ταυτόχρονα, θα ορίσουμε νέες λειτουργίες που θα γράφουν στην οθόνη με πιο άνετο τρόπο (όχι, δεν πρόκειται να εφαρμόσουμε το printf ακόμη, ξέρω ότι το θέλετε). Θα δημιουργήσουμε ένα αρχείο και την κεφαλίδα του για ένα σύνολο λειτουργιών που σχετίζονται με την οθόνη (ND_Screen.cpp και ND_Screen.hpp). Σε αυτά πρόκειται να δημιουργήσουμε λειτουργίες για: να αλλάξουμε το χρώμα των γραμμάτων και του φόντου, να γράψουμε φράσεις και γράμματα, να καθαρίσουμε την οθόνη και να μετακινηθούμε στην οθόνη. Συνεχίζουμε να χρησιμοποιούμε τις οθόνες VGA αλλά τώρα θα χρησιμοποιήσουμε μερικά byte που θα δώσουν το χρώμα. Το ND_Screen.cpp θα μοιάζει με:

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

Η κεφαλίδα θα είναι πολύ βασική, οπότε δεν το συμπεριλαμβάνω εδώ, αλλά επισημαίνω τον ορισμό του τύπου ND_SIDE

typedef enum ND_SIDE{
ND_SIDE_BACKGROUND,
ND_SIDE_FOREGROUND
} ND_SIDE;

Αναφέρετε επίσης ότι χρησιμοποιούμε την κεφαλίδα ND_Types.hpp, αυτή η κεφαλίδα ορίζει μερικούς βασικούς τύπους για uint8_t, uint16_t, κ.λπ. βάσει char και int. Στην πραγματικότητα αυτή η κεφαλίδα είναι αυτή στο πρότυπο C99 και στην πραγματικότητα το ND_Types.hpp μου είναι αντιγραφή/επικόλληση του αρχείου desde Linux, ώστε να μπορείτε να τα ανταλλάξετε και δεν θα γινόταν τίποτα (υπάρχουν μόνο ορισμοί, καμία συνάρτηση).

Για να ελέγξουμε εάν αυτός ο κώδικας λειτουργεί, θα τροποποιήσουμε το σημείο εισόδου C του πυρήνα:

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

Και αν ακολουθήσουμε αυτά τα βήματα θα έχουμε αυτό το αποτέλεσμα

Επόμενο Επίπεδο-3

Χάρη σε αυτές τις λειτουργίες που έχουμε δημιουργήσει, μπορούμε να αρχίσουμε να δημιουργούμε μικρά GUI, όπως έναν πανικό πυρήνα που θα εμφανίζουμε κάθε φορά που υπάρχει ένα ανεπανόρθωτο σφάλμα. Κάτι σαν αυτό:

Επόμενο Επίπεδο-4

Και αυτό το μικρό GUI το κάναμε μόνο με αυτές τις λειτουργίες:

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

Και μέχρι εδώ η ανάρτηση. Σας υπενθυμίζω τις οδηγίες για τη μεταγλώττιση του συστήματος από το 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

Και εκμεταλλεύομαι αυτήν την ευκαιρία για να σας ευχαριστήσω για την εξαιρετική υποδοχή που είχε η πρώτη ανάρτηση.


Αφήστε το σχόλιό σας

Η διεύθυνση email σας δεν θα δημοσιευθεί. Τα υποχρεωτικά πεδία σημειώνονται με *

*

*

  1. Υπεύθυνος για τα δεδομένα: Miguel Ángel Gatón
  2. Σκοπός των δεδομένων: Έλεγχος SPAM, διαχείριση σχολίων.
  3. Νομιμοποίηση: Η συγκατάθεσή σας
  4. Κοινοποίηση των δεδομένων: Τα δεδομένα δεν θα κοινοποιούνται σε τρίτους, εκτός από νομική υποχρέωση.
  5. Αποθήκευση δεδομένων: Βάση δεδομένων που φιλοξενείται από τα δίκτυα Occentus (ΕΕ)
  6. Δικαιώματα: Ανά πάσα στιγμή μπορείτε να περιορίσετε, να ανακτήσετε και να διαγράψετε τις πληροφορίες σας.

  1.   f3niX dijo

    Εξαιρετικός φίλος, ακόμα κι έτσι σκοτώνω το κράνος μου καταλαβαίνοντας τον κωδικό στο c ++.

    Χαιρετισμούς.

  2.   πανδακρίς dijo

    αυτά τα είδη είναι υπέροχα. Έκαναν πάλι την περιέργειά μου για τη χαμηλή απόδοση των επεξεργαστών για άλλη μια φορά.
    Ίσως αν έχω χρόνο να ξεκινήσω να παίζω με την επόμενη κατάδυση.
    Δεν έχω στείλει ένα άρθρο για πολύ καιρό. ήδη χρειάζεται

  3.   Τζον λαγούρα dijo

    Εντάξει, αυτός είναι ο τρόπος.

  4.   miguel dijo

    Ήθελα από καιρό να μάθω πώς να φτιάξω ένα λειτουργικό σύστημα.

    Περιμένοντας την επόμενη ανάρτησή σας. Στην υγειά σας

  5.   Giuliano dijo

    Ωραία φίλη!
    Απλώς έχω πρόβλημα, μπορεί κάποιος να μου περάσει ένα αρχείο στο C αυτού του παραδείγματος;
    Μου στέλνει πάντα σφάλματα στο τερματικό