Maligayang pagdating sa isa pang post sa kung paano lumikha ng aming sariling operating system, sa kasong ito NextDivel.
Kung babalik tayo sa code ng unang post sa pagtatapos ng lahat ng bagay dapat magkaroon kami ng ganitong bagay:
Kung ito ay tama maaari nating ipagpatuloy. Gagamitin ko ang system at istraktura na mayroon ako sa GitHub (http://github.com/AdrianArroyoCalle/next-divel) dahil mas komportable ito para sa akin at sa iyo. Tulad ng nakikita mo ang teksto ay isang pangunahing teksto, hindi ito kaakit-akit. Maaaring parang isang bagay na hindi karaniwan. Ngunit tulad ng sinasabi ng kasabihan, upang tikman ang mga kulay, at sa aming operating system ay magkakaroon ng mga kulay. Ang mga unang kulay na mailalagay namin ay ang mga tumutukoy sa mga VGA card at sila ay 0:
- Itim
- Azul
- Berde
- Cyan
- Pula
- Kulay-pula
- Kayumanggi
- Banayad na kulay-abo
- Madilim na kulay-abo
- Banayad na asul
- Banayad na berde
- Cyan malinaw
- Banayad na pula
- Magaan na magenta
- Magaan na kayumanggi
- Blanco
Tutukuyin namin ang mga kulay na ito sa isang header upang magkaroon ito ng mas madaling gamiting at marahil sa hinaharap ay maging bahagi ng system API. Kaya nilikha namin ang file na ND_Colors.hpp sa kasunod na NextDivel.
#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
Sa parehong oras ay tutukuyin namin ang mga bagong pag-andar upang magsulat sa screen sa isang mas komportableng paraan (hindi, hindi pa kami magpapatupad ng printf, alam kong nais mo ito). Lilikha kami ng isang file at ang header nito para sa isang hanay ng mga pag-andar na nauugnay sa screen (ND_Screen.cpp at ND_Screen.hpp). Sa mga ito lilikha kami ng mga pagpapaandar upang: baguhin ang kulay ng mga titik at background, magsulat ng mga parirala at titik, linisin ang screen at ilipat ang paligid ng screen. Patuloy kaming gumagamit ng mga VGA screen ngunit ngayon ay gagamit kami ng ilang mga byte na magbibigay ng kulay. Ang ND_Screen.cpp ay magiging katulad ng:
/**
* @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;
}
Ang header ay magiging napaka-basic kaya hindi ko ito isinasama dito, ngunit i-highlight ang kahulugan ng uri ng ND_SIDE
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).
Upang masubukan kung gumagana ang code na ito ay babago namin ang C entry point ng kernel:
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");
At kung susundin natin ang mga hakbang na ito makukuha natin ang resulta na ito
Salamat sa mga pagpapaandar na nilikha namin, maaari kaming magsimulang gumawa ng maliliit na GUI, tulad ng isang kernel panic na ipapakita namin sa tuwing may isang hindi maibabalik na error. Isang bagay na tulad nito:
At ang maliit na GUI na ito ay ginawa lamang namin sa mga pagpapaandar na ito:
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);
}
At hanggang dito ang post. Ipinaaalala ko sa iyo ang mga tagubilin na itala ang system mula sa 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
At kinukuha ko ang opurtunidad na ito upang salamat sa mahusay na pagtanggap sa unang post.
Mahusay na kaibigan, kahit na pinapatay ko ang aking helmet na nauunawaan ang code sa c ++.
Pagbati.
magagaling ang mga item na ito. Inilagay nila ang aking pag-usisa tungkol sa mababang antas ng pagganap ng mga processor muli.
marahil kung may oras ako magsisimulang maglaro ako sa susunod na divel.
Matagal na akong hindi nagpapadala ng isang artikulo. kailangan na
Sige, ganun.
Matagal ko nang gustong malaman kung paano bumuo ng isang operating system.
Naghihintay para sa iyong susunod na post. Cheers
Mahusay na kaibigan!
Mayroon lamang akong isang problema, maaari bang ipasa ng isang tao sa akin ang isang C file ng halimbawang ito?
Palagi itong nagpapadala sa akin ng mga error sa terminal