ยินดีต้อนรับสู่โพสต์อื่นเกี่ยวกับวิธีสร้างระบบปฏิบัติการของเราเองในกรณีนี้ NextDivel
ถ้าเรากลับไปที่รหัสของ โพสต์แรก ในตอนท้ายของทุกสิ่งเราควรได้รับสิ่งนี้:
หากถูกต้องเราสามารถดำเนินการต่อได้ ฉันจะใช้ระบบและโครงสร้างที่ฉันมีใน GitHub (http://github.com/AdrianArroyoCalle/next-divel) เพราะสะดวกสบายกว่าสำหรับฉันและคุณ ดังที่คุณเห็นข้อความเป็นข้อความพื้นฐานไม่น่าสนใจ มันอาจดูเหมือนบางอย่างที่ไม่ธรรมดา แต่อย่างที่กล่าวไปเพื่อลิ้มรสสีและในระบบปฏิบัติการของเราจะมีสี สีแรกที่เราจะใส่ได้จะเป็นสีที่กำหนดการ์ด VGA และเป็น 0:
- สีดำ
- Azul
- สีเขียว
- Cyan
- โรโจ
- สีม่วงแดงเข้ม
- สีน้ำตาล
- สีเทาอ่อน
- กริสออสคูโร
- สีฟ้าอ่อน
- เขียวอ่อน
- สีฟ้าใส
- แสงสีแดง
- ม่วงแดงอ่อน
- สีน้ำตาลอ่อน
- blanco
เราจะกำหนดสีเหล่านี้ในส่วนหัวเพื่อให้มีประโยชน์มากขึ้นและบางทีอาจจะกลายเป็นส่วนหนึ่งของ 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 ต่อไป แต่ตอนนี้เราจะใช้ไม่กี่ไบต์ที่จะให้สี 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 ฯลฯ โดยอิงตามอักขระและ 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");
และถ้าเราทำตามขั้นตอนเหล่านี้เราจะได้ผลลัพธ์นี้
ด้วยฟังก์ชันเหล่านี้ที่เราสร้างขึ้นเราสามารถเริ่มสร้าง GUI ขนาดเล็กเช่นเคอร์เนลแพนิคที่เราจะแสดงทุกครั้งที่มีข้อผิดพลาดที่ไม่สามารถกู้คืนได้ สิ่งนี้:
และ 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
และฉันถือโอกาสนี้ขอบคุณสำหรับการต้อนรับที่ดีเยี่ยมที่โพสต์แรก
เพื่อนที่ยอดเยี่ยมถึงขนาดที่ฉันฆ่าหมวกกันน็อคเข้าใจรหัสใน c ++
อาศิรพจน์
รายการเหล่านี้ดีมาก พวกเขาทำให้ฉันอยากรู้อยากเห็นเกี่ยวกับประสิทธิภาพระดับต่ำของโปรเซสเซอร์อีกครั้ง
บางทีถ้าฉันมีเวลาฉันจะเริ่มเล่นกับ next-divel
ไม่ได้ส่งบทความมานานแล้ว จำเป็นแล้ว
เอาล่ะนั่นคือวิธี
ฉันอยากรู้วิธีสร้างระบบปฏิบัติการมานานแล้ว
รอกระทู้หน้านะ ไชโย
เพื่อนที่ดี!
ฉันมีปัญหาใครสามารถส่งไฟล์ใน C ของตัวอย่างนี้ให้ฉันได้ไหม
มันมักจะส่งข้อผิดพลาดในเทอร์มินัลให้ฉัน