Selamat datang di entri lain mengenai cara membuat sistem operasi kita sendiri, dalam hal ini NextDivel.
Sekiranya kita kembali ke kod jawatan pertama pada akhir semua yang sepatutnya kita buat seperti ini:
Sekiranya ini betul, kita boleh teruskan. Saya akan menggunakan sistem dan struktur yang saya ada di GitHub (http://github.com/AdrianArroyoCalle/next-divel) kerana ia lebih selesa untuk saya dan anda. Seperti yang anda lihat teks itu adalah teks asas, tidak menarik. Mungkin kelihatan seperti sesuatu yang tidak biasa. Tetapi seperti kata pepatah, untuk merasakan warna, dan dalam sistem operasi kita akan ada warna. Warna pertama yang akan dapat kita letakkan ialah warna yang menentukan kad VGA dan ia adalah 0:
- Hitam
- Azul
- Hijau
- Sian
- Merah
- Magenta
- Coklat
- Kelabu muda
- Kelabu gelap
- Biru muda
- Cahaya hijau
- Sian jelas
- Lampu merah
- Magenta ringan
- Coklat muda
- White
Kami akan menentukan warna-warna ini dalam tajuk untuk menjadikannya lebih berguna dan mungkin pada masa akan datang menjadi sebahagian daripada sistem API. Oleh itu, kami membuat fail ND_Colors.hpp di NextDivel termasuk.
#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
Pada masa yang sama kita akan menentukan fungsi baru untuk menulis di layar dengan cara yang lebih selesa (tidak, kita belum akan melaksanakan printf, saya tahu anda menginginkannya). Kami akan membuat fail dan tajuknya untuk sekumpulan fungsi yang berkaitan dengan skrin (ND_Screen.cpp dan ND_Screen.hpp). Di dalamnya kita akan membuat fungsi untuk: mengubah warna huruf dan latar belakang, menulis ayat dan huruf, membersihkan layar dan bergerak di sekitar layar. Kami terus menggunakan skrin VGA tetapi sekarang kami akan menggunakan beberapa bait yang akan memberi warna. ND_Screen.cpp akan kelihatan seperti:
/**
* @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;
}
Pengepala akan sangat asas jadi saya tidak memasukkannya di sini, tetapi sorot definisi jenis 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).
Untuk menguji apakah kod ini berfungsi, kita akan mengubah titik masuk 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");
Dan jika kita mengikuti langkah-langkah ini, kita akan mendapat hasil ini
Berkat fungsi-fungsi ini yang telah kami buat, kami dapat mulai membuat GUI kecil, seperti kernel panik yang akan kami tunjukkan setiap kali ada kesalahan yang tidak dapat dipulihkan. Sesuatu seperti ini:
Dan GUI kecil ini kami buat hanya dengan fungsi berikut:
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);
}
Dan sampai di sini jawatan. Saya mengingatkan anda tentang arahan untuk menyusun sistem dari 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
Dan saya mengambil kesempatan ini untuk mengucapkan terima kasih atas penerimaan yang sangat baik dari siaran pertama.
Rakan yang baik, walaupun begitu saya menggunakan topi keledar saya memahami kod di c ++.
Greetings.
barang-barang ini hebat. mereka telah menimbulkan rasa ingin tahu saya mengenai prestasi pemproses tahap rendah sekali lagi.
mungkin jika saya mempunyai masa saya akan mula bermain dengan permainan seterusnya.
Sudah lama saya tidak menghantar artikel. sudah diperlukan
Baiklah, itulah caranya.
Saya sudah lama ingin mengetahui bagaimana membina sistem operasi.
Menunggu catatan anda yang seterusnya. salam
Kawan terbaik!
Saya hanya mempunyai satu masalah, bolehkah seseorang menyampaikan fail C contoh ini kepada saya?
Ia selalu menghantar saya kesalahan di terminal