Linus Torvalds 에뮬레이션 : 처음부터 자신 만의 운영 체제 만들기 (II)

자체 운영 체제 (이 경우 NextDivel)를 만드는 방법에 대한 다른 게시물에 오신 것을 환영합니다.

우리가 코드로 돌아 가면 첫 번째 게시물 모든 것이 끝날 때 우리는 다음과 같은 것을 생각해 내야합니다.

다음다이벌-1

이것이 맞다면 계속할 수 있습니다. GitHub에있는 시스템과 구조를 사용하겠습니다 (http://github.com/AdrianArroyoCalle/next-divel) 저와 당신에게 더 편안하기 때문입니다. 보시다시피 텍스트는 기본 텍스트이므로 매력적이지 않습니다. 평범하지 않은 것처럼 보일 수 있습니다. 그러나 속담처럼 색상을 맛보고 우리 운영 체제에는 색상이 있습니다. 우리가 넣을 수있는 첫 번째 색상은 VGA 카드를 정의하는 색상이며 0입니다.

  1. 흑인
  2. 봤어
  3. 녹색
  4. 청록색
  5. 로조
  6. 마젠타
  7. 브라운
  8. 라이트 그레이
  9. 짙은 회색
  10. 하늘색
  11. 연한 녹색
  12. 청록색 투명
  13. 라이트 레드
  14. 라이트 마젠타
  15. 연한 갈색
  16. 블랑코

더 편리하게 사용할 수 있도록 헤더에 이러한 색상을 정의하고 향후 시스템 API의 일부가 될 것입니다. 따라서 NextDivel include에 ND_Colors.hpp 파일을 만듭니다.

#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 헤더를 사용한다는 점을 언급하세요. 이 헤더는 char 및 int를 기반으로 uint8_t, uint16_t 등에 대한 몇 가지 기본 유형을 정의합니다. 실제로 이 헤더는 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");

이 단계를 따르면이 결과를 얻을 수 있습니다.

다음다이벌-3

우리가 만든 이러한 기능 덕분에 복구 할 수없는 오류가 발생할 때마다 표시되는 커널 패닉과 같은 작은 GUI를 만들기 시작할 수 있습니다. 이 같은:

다음다이벌-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 Ángel Gatón
  2. 데이터의 목적 : 스팸 제어, 댓글 관리.
  3. 합법성 : 귀하의 동의
  4. 데이터 전달 : 법적 의무에 의한 경우를 제외하고 데이터는 제 XNUMX 자에게 전달되지 않습니다.
  5. 데이터 저장소 : Occentus Networks (EU)에서 호스팅하는 데이터베이스
  6. 권리 : 귀하는 언제든지 귀하의 정보를 제한, 복구 및 삭제할 수 있습니다.

  1.   f3niX

    훌륭한 친구여, 그래도 C ++의 코드를 이해하는 헬멧을 죽이고 있습니다.

    인사말.

  2.   판다 크리스

    이 항목은 훌륭합니다. 그들은 프로세서의 저수준 성능에 대해 다시 한 번 호기심을 불러 일으켰습니다.
    시간이 있으면 다음 디벨로 게임을 시작할 것입니다.
    나는 오랫동안 기사를 보내지 않았습니다. 이미 필요

  3.   존 버로우스

    좋아, 그게 방법이야.

  4.   미겔

    저는 오랫동안 운영 체제를 구축하는 방법을 알고 싶었습니다.

    다음 게시물을 기다리고 있습니다. 문안 인사

  5.   아노

    좋은 친구!
    한 가지 문제가 있습니다. 누군가가이 예제의 C 파일을 전달할 수 있습니까?
    항상 터미널에서 오류를 보냅니다.