Linus Torvalds'ı Taklit Etmek: Kendi işletim sisteminizi sıfırdan oluşturun (II)

Kendi işletim sistemimizi nasıl yaratacağımızı anlatan başka bir gönderiye hoş geldiniz, bu durumda NextDivel.

Koduna geri dönersek ilk sonrası her şeyin sonunda şunun gibi bir şey bulmalıydık:

SonrakiDalış-1

Bu doğruysa devam edebiliriz. GitHub'da sahip olduğum sistemi ve yapıyı kullanacağım (http://github.com/AdrianArroyoCalle/next-divelbenim ve senin için daha rahat olduğu için. Gördüğünüz gibi metin basit bir metin, çekici değil. Sıradışı bir şey gibi görünebilir. Ama söylenildiği gibi, renkleri tatmak için ve işletim sistemimizde renkler olacak. Koyabileceğimiz ilk renkler VGA kartlarını tanımlayanlar olacak ve bunlar 0:

  1. Zenci
  2. mavi
  3. Yeşil
  4. Mavi
  5. Rojo
  6. eflatun
  7. kahverengi
  8. Açık gri
  9. Koyu gri
  10. Açık mavi
  11. Açık yeşil
  12. Açık mavi
  13. Açık kırmızı
  14. Açık eflatun
  15. Açık kahverengi
  16. Blanco

Daha kullanışlı olması ve belki de gelecekte sistem API'sinin bir parçası haline gelmesi için bu renkleri bir başlıkta tanımlayacağız. Bu yüzden NextDivel dahilinde ND_Colors.hpp dosyasını oluşturuyoruz.

#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

Aynı zamanda daha rahat bir şekilde ekrana yazmak için yeni fonksiyonlar tanımlayacağız (hayır, henüz printf uygulamayacağız, istekli olduğunu biliyorum). Ekranla ilgili bir dizi işlev (ND_Screen.cpp ve ND_Screen.hpp) için bir dosya ve onun başlığını oluşturacağız. Bunlarda, harflerin ve arka planın rengini değiştirmek, ifadeler ve harfler yazmak, ekranı temizlemek ve ekranda hareket etmek için işlevler oluşturacağız. VGA ekranları kullanmaya devam ediyoruz ama şimdi rengi verecek birkaç bayt kullanacağız. ND_Screen.cpp şöyle görünür:

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

Başlık çok basit olacak, bu yüzden buraya dahil etmiyorum, ancak ND_SIDE türünün tanımını vurgulayın

typedef enum ND_SIDE{
ND_SIDE_BACKGROUND,
ND_SIDE_FOREGROUND
} ND_SIDE;

Ayrıca ND_Types.hpp başlığını kullandığımızdan da bahsedin, bu başlık uint8_t, uint16_t, vb. İçin char ve int'e göre bazı temel türleri tanımlar. Aslında bu başlık C99 standardındakidir ve aslında benim ND_Types.hpp dosyanın Linux'tan kopyalanması / yapıştırılmasıdır, böylece onları değiştirebilir ve hiçbir şey olmaz (sadece tanımlar vardır, işlevler yoktur).

Bu kodun çalışıp çalışmadığını test etmek için çekirdeğin C giriş noktasını değiştireceğiz:

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

Ve bu adımları izlersek, bu sonucu alırız

SonrakiDalış-3

Oluşturduğumuz bu fonksiyonlar sayesinde kurtarılamaz bir hata olduğunda her seferinde göstereceğimiz bir çekirdek paniği gibi küçük GUI'ler yapmaya başlayabiliriz. Bunun gibi bir şey:

SonrakiDalış-4

Ve bu küçük GUI'yi yalnızca şu işlevlerle yaptık:

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

Ve işte gönderi. Sistemi 0'dan derlemek için talimatları size hatırlatıyorum:

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

Ve bu vesileyle ilk gönderinin mükemmel karşılaması için size teşekkür etmek istiyorum.


Makalenin içeriği şu ilkelerimize uygundur editoryal etik. Bir hata bildirmek için tıklayın burada.

5 yorum, sizinkini bırakın

Yorumunuzu bırakın

E-posta hesabınız yayınlanmayacak.

*

*

  1. Verilerden sorumlu: Miguel Ángel Gatón
  2. Verilerin amacı: Kontrol SPAM, yorum yönetimi.
  3. Meşruiyet: Onayınız
  4. Verilerin iletilmesi: Veriler, yasal zorunluluk dışında üçüncü kişilere iletilmeyecektir.
  5. Veri depolama: Occentus Networks (AB) tarafından barındırılan veritabanı
  6. Haklar: Bilgilerinizi istediğiniz zaman sınırlayabilir, kurtarabilir ve silebilirsiniz.

  1.   F3niX dijo

    Mükemmel arkadaşım, buna rağmen kaskımı c ++ 'daki kodu anlayarak öldürüyorum.

    Selamlar.

  2.   Pandacriss dijo

    bu öğeler harika. İşlemcilerin düşük seviyeli performansına dair merakımı bir kez daha uyandırdılar.
    belki zamanım olursa bir sonraki dalda oynamaya başlayacağım.
    Uzun zamandır makale göndermedim. zaten gerekli

  3.   Jon burrows dijo

    Pekala, yol bu.

  4.   miguel dijo

    Uzun zamandır bir işletim sisteminin nasıl kurulacağını bilmek istedim.

    Bir sonraki gönderinizi bekliyorum. Şerefe

  5.   Giuliano dijo

    Harika arkadaş!
    Sadece bir problemim var, birisi bana bu örneğin C dosyasını iletebilir mi?
    Bana her zaman terminalde hatalar gönderir

bool(doğru)