การจำลอง Linus Torvalds: สร้างระบบปฏิบัติการของคุณเองตั้งแต่เริ่มต้น (II)

ยินดีต้อนรับสู่โพสต์อื่นเกี่ยวกับวิธีสร้างระบบปฏิบัติการของเราเองในกรณีนี้ NextDivel

ถ้าเรากลับไปที่รหัสของ โพสต์แรก ในตอนท้ายของทุกสิ่งเราควรได้รับสิ่งนี้:

ต่อไปDive-1

หากถูกต้องเราสามารถดำเนินการต่อได้ ฉันจะใช้ระบบและโครงสร้างที่ฉันมีใน GitHub (http://github.com/AdrianArroyoCalle/next-divel) เพราะสะดวกสบายกว่าสำหรับฉันและคุณ ดังที่คุณเห็นข้อความเป็นข้อความพื้นฐานไม่น่าสนใจ มันอาจดูเหมือนบางอย่างที่ไม่ธรรมดา แต่อย่างที่กล่าวไปเพื่อลิ้มรสสีและในระบบปฏิบัติการของเราจะมีสี สีแรกที่เราจะใส่ได้จะเป็นสีที่กำหนดการ์ด VGA และเป็น 0:

  1. สีดำ
  2. Azul
  3. สีเขียว
  4. Cyan
  5. โรโจ
  6. สีม่วงแดงเข้ม
  7. สีน้ำตาล
  8. สีเทาอ่อน
  9. กริสออสคูโร
  10. สีฟ้าอ่อน
  11. เขียวอ่อน
  12. สีฟ้าใส
  13. แสงสีแดง
  14. ม่วงแดงอ่อน
  15. สีน้ำตาลอ่อน
  16. 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");

และถ้าเราทำตามขั้นตอนเหล่านี้เราจะได้ผลลัพธ์นี้

ต่อไปDive-3

ด้วยฟังก์ชันเหล่านี้ที่เราสร้างขึ้นเราสามารถเริ่มสร้าง GUI ขนาดเล็กเช่นเคอร์เนลแพนิคที่เราจะแสดงทุกครั้งที่มีข้อผิดพลาดที่ไม่สามารถกู้คืนได้ สิ่งนี้:

ต่อไปDive-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

และฉันถือโอกาสนี้ขอบคุณสำหรับการต้อนรับที่ดีเยี่ยมที่โพสต์แรก


แสดงความคิดเห็นของคุณ

อีเมล์ของคุณจะไม่ถูกเผยแพร่ ช่องที่ต้องการถูกทำเครื่องหมายด้วย *

*

*

  1. ผู้รับผิดชอบข้อมูล: Miguel ÁngelGatón
  2. วัตถุประสงค์ของข้อมูล: ควบคุมสแปมการจัดการความคิดเห็น
  3. ถูกต้องตามกฎหมาย: ความยินยอมของคุณ
  4. การสื่อสารข้อมูล: ข้อมูลจะไม่ถูกสื่อสารไปยังบุคคลที่สามยกเว้นตามข้อผูกพันทางกฎหมาย
  5. การจัดเก็บข้อมูล: ฐานข้อมูลที่โฮสต์โดย Occentus Networks (EU)
  6. สิทธิ์: คุณสามารถ จำกัด กู้คืนและลบข้อมูลของคุณได้ตลอดเวลา

  1.   f3niX dijo

    เพื่อนที่ยอดเยี่ยมถึงขนาดที่ฉันฆ่าหมวกกันน็อคเข้าใจรหัสใน c ++

    อาศิรพจน์

  2.   แพนดาคริส dijo

    รายการเหล่านี้ดีมาก พวกเขาทำให้ฉันอยากรู้อยากเห็นเกี่ยวกับประสิทธิภาพระดับต่ำของโปรเซสเซอร์อีกครั้ง
    บางทีถ้าฉันมีเวลาฉันจะเริ่มเล่นกับ next-divel
    ไม่ได้ส่งบทความมานานแล้ว จำเป็นแล้ว

  3.   จอนโพรง dijo

    เอาล่ะนั่นคือวิธี

  4.   มิเกล dijo

    ฉันอยากรู้วิธีสร้างระบบปฏิบัติการมานานแล้ว

    รอกระทู้หน้านะ ไชโย

  5.   โน dijo

    เพื่อนที่ดี!
    ฉันมีปัญหาใครสามารถส่งไฟล์ใน C ของตัวอย่างนี้ให้ฉันได้ไหม
    มันมักจะส่งข้อผิดพลาดในเทอร์มินัลให้ฉัน