[OS]miniOS-9

๐Ÿ‘‰๏ธ 32๋น„ํŠธ ๋ณดํ˜ธ๋ชจ๋“œ์—์„œ ํ™”๋ฉด์— ๊ธ€์ž์“ฐ๋Š” ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค.(๊ทธ๋ž˜ํ”ฝ ๋ชจ๋“œ ์œ ์ง€์ƒํƒœ)
This is code for writing text to the screen in 32-bit protected mode (while maintaining graphics mode).

๐Ÿ‘‰๏ธ ํŒŒ์ผ / files

— kernel.cํŒŒ์ผ์„ ์ œ์™ธํ•˜๊ณค ๊ธฐ์กด์˜ ๋‚ด์šฉ๊ณผ ๋™์ผํ•ฉ๋‹ˆ๋‹ค.
Except for the kernel.c file, the contents are identical to the original.

boot.asm  kernel.c  sector2.asm

๐Ÿ‘‰๏ธ ์ฝ”๋“œ / Code

โœ”๏ธ kernel.c

typedef unsigned char byte;

// ------------------------------------------------------------------------
// 1. ๊ธฐ๋ณธ ๊ทธ๋ž˜ํ”ฝ ํ•จ์ˆ˜ (volatile ์ ์šฉ์œผ๋กœ ๋ฉ”๋ชจ๋ฆฌ ๊ฐ•์ œ ์“ฐ๊ธฐ)
// Basic graphics functions (forced memory write via volatile)
// ------------------------------------------------------------------------
void draw_pixel(int x, int y, byte color) {
    volatile byte *vram = (volatile byte *)0xA0000;
    vram[(y * 320) + x] = color;
}

void clear_screen(byte color) {
    for (int y = 0; y < 200; y++) {
        for (int x = 0; x < 320; x++) {
            draw_pixel(x, y, color);
        }
    }
}

// ------------------------------------------------------------------------
// 2. ๊ธ€์ž ์ถœ๋ ฅ ํ•จ์ˆ˜ (ํฐํŠธ ๋ฐ์ดํ„ฐ๋ฅผ ํ•จ์ˆ˜ ๋‚ด๋ถ€๋กœ ์ด๋™ํ•˜์—ฌ ๋งํ‚น ์˜ค๋ฅ˜ ํ•ด๊ฒฐ)
// Character output function (resolved linking errors by moving font data inside the function)
// ------------------------------------------------------------------------
void draw_char(int start_x, int start_y, int font_index, byte color) {
    // ๋ง์ปค ์˜ค๋ฅ˜๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ํฐํŠธ ๋ฐ์ดํ„ฐ๋ฅผ ํ•จ์ˆ˜ ๋‚ด๋ถ€ ์ง€์—ญ ๋ณ€์ˆ˜๋กœ ์„ ์–ธํ•ฉ๋‹ˆ๋‹ค.
    // To prevent linker errors, declare the font data as a local variable within the function.
    byte font_8x8[6][8] = {
        {0x18, 0x24, 0x42, 0x7E, 0x42, 0x42, 0x42, 0x00}, // A (index 0)
        {0x7C, 0x42, 0x42, 0x7C, 0x42, 0x42, 0x7C, 0x00}, // B (index 1)
        {0x3C, 0x42, 0x40, 0x40, 0x40, 0x42, 0x3C, 0x00}, // C (index 2)
        {0x78, 0x44, 0x42, 0x42, 0x42, 0x44, 0x78, 0x00}, // D (index 3)
        {0x7E, 0x40, 0x40, 0x78, 0x40, 0x40, 0x7E, 0x00}, // E (index 4)
        {0x7E, 0x40, 0x40, 0x78, 0x40, 0x40, 0x40, 0x00}  // F (index 5)
    };

    for (int y = 0; y < 8; y++) {
        byte row_data = font_8x8[font_index][y];
        
        for (int x = 0; x < 8; x++) {
            // ๋น„ํŠธ ๋งˆ์Šคํ‚น ์—ฐ์‚ฐ์œผ๋กœ 1์ธ ๋ถ€๋ถ„๋งŒ ์ ์„ ์ฐ์Œ
            // Plot points only at positions corresponding to 1s using bitmasking operations.
            if ((row_data & (0x80 >> x)) != 0) {
                draw_pixel(start_x + x, start_y + y, color);
            }
        }
    }
}

// ------------------------------------------------------------------------
// 3. ์ปค๋„ ๋ฉ”์ธ ํ•จ์ˆ˜
// Kernel main function
// ------------------------------------------------------------------------
void kernel_main(void) {
    // ๋ฐฐ๊ฒฝ์„ ํŒŒ๋ž€์ƒ‰(1)์œผ๋กœ ์ดˆ๊ธฐํ™”
    // Reset the background to blue (1).
    clear_screen(1);

    // ํ™”๋ฉด ์ค‘์•™(X=100, Y=80) ๊ทผ์ฒ˜์— ๋‹ค๋ฅธ ์ƒ‰์ƒ์œผ๋กœ A, B, C, D, E, F ์ถœ๋ ฅ
    // Display A, B, C, D, E, and F in different colors near the center of the screen (X=100, Y=80)
    draw_char(100, 80,  0, 15); // ํฐ์ƒ‰/white 'A'
    draw_char(112, 80,  1, 14); // ๋…ธ๋ž€์ƒ‰/yellow 'B'
    draw_char(124, 80,  2, 10); // ์ดˆ๋ก์ƒ‰/green 'C'
    draw_char(136, 80,  3, 12); // ๋นจ๊ฐ„์ƒ‰/red 'D'
    draw_char(148, 80,  4, 13); // ์ž์ƒ‰/Purple 'E'
    draw_char(160, 80,  5, 11); // ์ฒญ๋ก์ƒ‰/blue-green 'F'

    while (1) {
        __asm__ __volatile__("hlt");
    }
}

๐Ÿ‘‰๏ธ ์ฝ”๋“œ์„ค๋ช… / Code Explanation

โœ”๏ธ byte ํƒ€์ž…์„ ์–ธ / byte type declaration

typedef unsigned char byte;

— typedef

1)”Type Definition”์˜ ์ค„์ž„๋ง๋กœ, ๊ธฐ์กด์— ์กด์žฌํ•˜๋Š” ๋ฐ์ดํ„ฐ ํƒ€์ž…์— ์ƒˆ๋กœ์šด ๋ณ„๋ช…(๋ณ„์นญ)์„ ๋ถ™์—ฌ์ฃผ๋Š” ํ‚ค์›Œ๋“œ์ž…๋‹ˆ๋‹ค.
Short for “Type Definition,” this is a keyword used to assign a new alias to an existing data type.

2)๊ธด ์ด๋ฆ„์„ ์งง๊ฒŒ ์ค„์—ฌ์„œ ์‚ฌ์šฉ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค.
It allows you to shorten long names for use.

3)typeof๋ฌธ๋ฒ•์€ ์•„๋ž˜์ฒ˜๋ฆ„ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
The typeof syntax is used as shown below.

typedef [๊ธฐ์กด ์ž๋ฃŒํ˜•/Existing data type] [์ƒˆ๋กœ์šด ๋ณ„๋ช… /New alias];

4)typeof๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์•„๋ž˜์ฒ˜๋Ÿผ ๋ฐ์ดํ„ฐ ํƒ€์ž…์„ ์ค„์—ฌ์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
By using typeof, you can use a shortened form for the data type, as shown below.

# ๋ณ„์นญ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ
# When no alias is used
volatile unsigned char *vram = (volatile unsigned char *)0xA0000;

# ๋ณ„์นญ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ
# When using aliases
volatile byte *vram = (volatile byte *)0xA0000;

— unsigned char

1)C์–ธ์–ด์—์„œ ๊ธฐ๋ณธ์œผ๋กœ ์ œ๊ณตํ•˜๋Š” ๊ฐ€์žฅ ์ž‘์€ ๋‹จ์œ„์˜ ๋ฐ์ดํ„ฐ ์ž๋ฃŒํ˜•์ž…๋‹ˆ๋‹ค.
It is the smallest unit of data type provided by default in the C language.

2)char๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ 1๋ฐ”์ดํŠธ(8๋น„ํŠธ) ํฌ๊ธฐ์˜ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ฐ€์ง‘๋‹ˆ๋‹ค.
A char typically occupies 1 byte (8 bits) of memory.

3)unsigned๋Š” ‘๋ถ€ํ˜ธ๊ฐ€ ์—†๋‹ค’๋Š” ๋œป์ž…๋‹ˆ๋‹ค. ๋งˆ์ด๋„ˆ์Šค((-)) ์Œ์ˆ˜๋ฅผ ํ‘œํ˜„ํ•˜์ง€ ์•Š๊ฒ ๋‹ค๋Š” ์˜๋ฏธ์ž…๋‹ˆ๋‹ค.
‘Unsigned’ means ‘without a sign.’ It signifies that negative numbers (indicated by a minus sign) are not represented.

4)์ผ๋ฐ˜์ ์ธ char๋Š” (-128 ~ +127)๊นŒ์ง€ ํ‘œํ˜„ํ•˜์ง€๋งŒ, ๋ถ€ํ˜ธ๋ฅผ ์—†์•ค unsigned char๋Š” 8๋น„ํŠธ ์ „์ฒด๋ฅผ ์–‘์ˆ˜๋กœ๋งŒ ์‚ฌ์šฉํ•˜์—ฌ (0 ~ 255)๊นŒ์ง€ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
While a standard char represents values โ€‹โ€‹from -128 to +127, an unsigned charโ€”which removes the sign bitโ€”uses all 8 bits for positive values, allowing it to represent a range of 0 to 255.

โœ”๏ธ draw_pixelํ•จ์ˆ˜
draw_pixel function

— ํŠน์ • ์ขŒํ‘œ ((x, y))์— ์›ํ•˜๋Š” ์ƒ‰์ƒ์˜ ์ (ํ”ฝ์…€) ํ•˜๋‚˜๋ฅผ ์ฐ๋Š” ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค.
This is a function that plots a single point (pixel) of a desired color at specific coordinates (x, y).

— unsigned char

1)C์–ธ์–ด์—์„œ ๊ธฐ๋ณธ์œผ๋กœ ์ œ๊ณตํ•˜๋Š” ๊ฐ€์žฅ ์ž‘์€ ๋‹จ์œ„์˜ ๋ฐ์ดํ„ฐ ์ž๋ฃŒํ˜•์ž…๋‹ˆ๋‹ค.
It is the smallest unit of data type provided by default in the C language.

2)char๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ 1๋ฐ”์ดํŠธ(8๋น„ํŠธ) ํฌ๊ธฐ์˜ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ฐ€์ง‘๋‹ˆ๋‹ค.
A char typically occupies 1 byte (8 bits) of memory.

3)unsigned๋Š” ‘๋ถ€ํ˜ธ๊ฐ€ ์—†๋‹ค’๋Š” ๋œป์ž…๋‹ˆ๋‹ค. ๋งˆ์ด๋„ˆ์Šค((-)) ์Œ์ˆ˜๋ฅผ ํ‘œํ˜„ํ•˜์ง€ ์•Š๊ฒ ๋‹ค๋Š” ์˜๋ฏธ์ž…๋‹ˆ๋‹ค.
‘Unsigned’ means ‘without a sign.’ It signifies that negative numbers (indicated by a minus sign) are not represented.

4)์ผ๋ฐ˜์ ์ธ char๋Š” (-128 ~ +127)๊นŒ์ง€ ํ‘œํ˜„ํ•˜์ง€๋งŒ, ๋ถ€ํ˜ธ๋ฅผ ์—†์•ค unsigned char๋Š” 8๋น„ํŠธ ์ „์ฒด๋ฅผ ์–‘์ˆ˜๋กœ๋งŒ ์‚ฌ์šฉํ•˜์—ฌ (0 ~ 255)๊นŒ์ง€ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
While a standard char represents values โ€‹โ€‹from -128 to +127, an unsigned charโ€”which removes the sign bitโ€”uses all 8 bits for positive values, allowing it to represent a range of 0 to 255.

โœ”๏ธ draw_pixelํ•จ์ˆ˜
draw_pixel function

— ํŠน์ • ์ขŒํ‘œ ((x, y))์— ์›ํ•˜๋Š” ์ƒ‰์ƒ์˜ ์ (ํ”ฝ์…€) ํ•˜๋‚˜๋ฅผ ์ฐ๋Š” ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค.
This is a function that plots a single point (pixel) of a desired color at specific coordinates (x, y).

void draw_pixel(int x, int y, byte color) {
    volatile byte *vram = (volatile byte *)0xA0000;
    vram[(y * 320) + x] = color;
}

–draw_pixelํ•จ์ˆ˜ ํŒŒ๋ผ๋ฉ”ํ„ฐ
draw_pixel function parameters

1)x ๋Š” ๊ฐ€๋กœ์ขŒํ‘œ,y๋Š” ์„ธ๋กœ์ขŒํ‘œ์ด๋ฉฐ ๊ฐ€๋กœ๋Š” 319๋ฒˆ,์„ธ๋กœ 199๋ฒˆ๊นŒ์ง€ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.(ํ•ด์ƒ๋„ 300 x 200)
x represents the horizontal coordinate and y the vertical coordinate; the horizontal range is 0 to 319, and the vertical range is 0 to 199 (resolution: 300 x 200).

2)color๋Š” 256์ƒ‰์„ ์‚ฌ์šฉํ•˜๋ฏ€๋กœ 256๋ฒˆ๊นŒ์ง€ ์‚ฌ์šฉ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
Since the color setting uses a 256-color palette, values โ€‹โ€‹up to 256 can be used.

–0xA0000

1)IBM PC ํ˜ธํ™˜ ์ปดํ“จํ„ฐ์—์„œ VGA ๊ทธ๋ž˜ํ”ฝ ์นด๋“œ์˜ ํ™”๋ฉด ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ์‹œ์ž‘๋˜๋Š” ๋ฌผ๋ฆฌ์  ์ฃผ์†Œ์ž…๋‹ˆ๋‹ค. ์ด ์ฃผ์†Œ์— ๋ฐ์ดํ„ฐ๋ฅผ ์“ฐ๋ฉด ๋ชจ๋‹ˆํ„ฐ ํ™”๋ฉด์— ๊ทธ๋Œ€๋กœ ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๋‹ค.
This is the physical address where the screen memory of a VGA graphics card begins on an IBM PC-compatible computer. Writing data to this address causes it to appear directly on the monitor screen.

–volatile

1)์ปดํŒŒ์ผ๋Ÿฌ๋Š” ์†๋„๋ฅผ ๋†’์ด๊ธฐ ์œ„ํ•ด์„œ ํ•œ๋ฒˆ ์ฝ์–ด ์˜จ ๊ฐ’์„ cpu๋ ˆ์ง€์Šคํ„ฐ์— ์ €์žฅํ•ด๋‘๊ณ  ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
To increase speed, the compiler stores a value it has read into a CPU register and uses it from there.

2)volatileํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ ˆ์ง€์Šคํ„ฐ์˜ ๊ฐ’์„ ์ฐธ์กฐํ•˜์ง€ ์•Š๊ณ  ๋ฐ”๋กœ ๋ฉ”๋ชจ๋ฆฌ์—์„œ ๊ฐ’์„ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.
When the volatile keyword is used, the value is retrieved directly from memory instead of referencing the value in a register.

— ๋ฌธ์ž์˜ ์œ„์น˜ ์„ค์ •
Setting the text position

vram[(y * 320) + x] = color;

1)vram๋ฐฐ์—ด์€ ๋‹จ์ˆœ ๊ฐ’์˜ ๋‚˜์—ด์ด๊ณ  ๋‚˜์ค‘์— ์‹ค์ œ๋กœ X,Y์œ„์น˜๋ฅผ ์žก๊ธฐ์œ„ํ•ด ๋ฐ์ดํ„ฐ ์…‹ํŒ…ํ•ฉ๋‹ˆ๋‹ค.
The VRAM array is simply a sequence of values; the data is configured later to actually determine the X and Y positions.

— ํ™”๋ฉด์˜ ๋ฐฐ๊ฒฝ์ƒ‰์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.
Specifies the background color of the screen.

void clear_screen(byte color) {
    for (int y = 0; y < 200; y++) {
        for (int x = 0; x < 320; x++) {
            draw_pixel(x, y, color);
        }
    }
}

1)kernel_mainํ•จ์ˆ˜์—์„œ clear_screen(1)์„ ์ง€์ •ํ•ด์„œ ํ™”๋ฉด์„ ํŒŒ๋ž‘์ƒ‰์œผ๋กœ ์…‹ํŒ…ํ•ฉ๋‹ˆ๋‹ค.
In the kernel_main function, specify clear_screen(1) to set the screen color to blue.

void kernel_main(void) {
    // ๋ฐฐ๊ฒฝ์„ ํŒŒ๋ž€์ƒ‰(1)์œผ๋กœ ์ดˆ๊ธฐํ™”
    // Reset the background to blue (1).
    clear_screen(1);

    ...
}

โœ”๏ธ draw_charํ•จ์ˆ˜
draw_char function

— ‘A’์˜ ๋ฐ์ดํ„ฐ ์‹œ๊ฐํ™”
Data visualization of ‘A’

1){0x18, 0x24, 0x42, 0x7E, 0x42, 0x42, 0x42, 0x00}์„ 2์ง„์ˆ˜๋กœ ๋ฐ”๊พธ์–ด 8×8 ๋ชจ๋ˆˆ์ข…์ด์— ์ฑ„์šฐ๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ชจ์–‘์ด ๋‚˜์˜ต๋‹ˆ๋‹ค.
If you convert {0x18, 0x24, 0x42, 0x7E, 0x42, 0x42, 0x42, 0x00} into binary and fill in an 8×8 grid, the following shape is formed.

ํ–‰/Col (Y)16์ง„์ˆ˜/Hexadecimal2์ง„์ˆ˜ ๋ณ€ํ™˜ (8๋น„ํŠธ)
Binary Conversion (8-bit)
์‹ค์ œ ๊ธ€์ž ๋ชจ์–‘
Actual character shape
0๋ฒˆ์งธ/0th0x1800011000โ–‘โ–‘โ–‘โ–ˆโ–ˆโ–‘โ–‘โ–‘
1๋ฒˆ์งธ/1st0x2400100100โ–‘โ–‘โ–ˆโ–‘โ–‘โ–ˆโ–‘โ–‘
2๋ฒˆ์งธ/2nd0x4201000010โ–‘โ–ˆโ–‘โ–‘โ–‘โ–‘โ–ˆโ–‘
3๋ฒˆ์งธ/3rd0x7E01111110โ–‘โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–‘
4๋ฒˆ์งธ/4th0x4201000010โ–‘โ–ˆโ–‘โ–‘โ–‘โ–‘โ–ˆโ–‘
5๋ฒˆ์งธ/5th0x4201000010โ–‘โ–ˆโ–‘โ–‘โ–‘โ–‘โ–ˆโ–‘
6๋ฒˆ์งธ/6th0x4201000010โ–‘โ–ˆโ–‘โ–‘โ–‘โ–‘โ–ˆโ–‘
7๋ฒˆ์งธ/7th0x0000000000โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘

— ํ™”๋ฉด์— ๊ธ€์ž ๊ทธ๋ฆฌ๊ธฐ / Drawing text on the screen

    for (int y = 0; y < 8; y++) {
        byte row_data = font_8x8[font_index][y];
        
        for (int x = 0; x < 8; x++) {
            // ๋น„ํŠธ ๋งˆ์Šคํ‚น ์—ฐ์‚ฐ์œผ๋กœ 1์ธ ๋ถ€๋ถ„๋งŒ ์ ์„ ์ฐ์Œ
            // Plot points only at positions corresponding to 1s using bitmasking operations.
            if ((row_data & (0x80 >> x)) != 0) {
                draw_pixel(start_x + x, start_y + y, color);
            }
        }
    }

1)๋ฐ˜๋ณต๋ฌธ์ด ์‹คํ–‰๋˜๋ฉด์„œ font_8x8 ๋ฐฐ์—ด์—์„œ ํ•ด๋‹นํ•˜๋Š” ๋ฌธ์ž์˜ ๊ฐ’์„ ํ•˜๋‚˜์”ฉ ๊บผ๋ƒ…๋‹ˆ๋‹ค.
As the loop executes, it retrieves the values โ€‹โ€‹for the corresponding characters from the font_8x8 array one by one.

byte row_data = font_8x8[font_index][y];

2)0x80 >> x

2-1) 16์ง„์ˆ˜ 0x80์€ ์ด์ง„์ˆ˜๋กœ 10000000๊ฐ’์ด ๋ฉ๋‹ˆ๋‹ค.
The hexadecimal value 0x80 corresponds to the binary value 10000000.

2-2) ๋ฐ˜๋ณต๋ฌธ์ด ์‹คํ–‰๋˜๋ฉด x = 0 ์ผ ๋•Œ: 10000000,x = 1 ์ผ ๋•Œ: 01000000,x = 2 ์ผ ๋•Œ: 00100000 ์ด๋ ‡๊ฒŒ ๋น„ํŠธ๊ฐ€ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.
When the loop executes, the bits shift as follows: 10000000 when x = 0, 01000000 when x = 1, and 00100000 when x = 2.

3) row_data & (โ€ฆ)

3-1) ์•ค๋“œ ์—ฐ์‚ฐ์œผ๋กœ row_data์™€ 0x80 >> x๊ฐ’์„ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
Check row_data and the value of 0x80 >> x using an AND operation.

3-2)row_data๊ฐ€ A๋ฌธ์ž๋ฅผ ๊ทธ๋ฆฌ๊ณ  0x80 >> 0 ์ธ๊ฒฝ์šฐ๋กœ ์•ค๋“œ ์—ฐ์‚ฐ์˜ ๊ฒฐ๊ณผ๊ฐ€ 00000000 ์ด๋ฏ€๋กœ ์ ์„ ์ฐ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
If row_data represents the character ‘A’ and the operation is 0x80 >> 0, the result of the AND operation is 00000000, so no dot is drawn.

  00011000  (row_data: 'A'์˜ ์ฒซ ์ค„ / row_data: First line of 'A')
& 10000000  (0x80 >> 0)
------------
  00000000  

3-3) x=3์ผ๋•Œ 4๋ฒˆ์งธ ๋น„ํŠธ๊ฐ€ 1์ด ๋ฉ๋‹ˆ๋‹ค.

  00011000  (row_data: 'A'์˜ ์ฒซ ์ค„ / row_data: First line of 'A')
& 00010000  (0x80 >> 3)
------------
  00010000  

3-4)๋น„ํŠธ๊ฐ€ 1์ธ ๋ถ€๋ถ„์€ draw_pixelํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์ ์„ ์ฐ์Šต๋‹ˆ๋‹ค.
For parts where the bit is 1, a dot is drawn using the draw_pixel function.

draw_pixel(start_x + x, start_y + y, color);

3-5) ์ •๋ฆฌํ•˜๋ฉด ์ฒซ๋ฒˆ์งธ์ค„๋ถ€ํ„ฐ 8๋ฒˆ์งธ ์ค„๊นŒ์ง€ ์ขŒ์ธก์—์„œ ์šฐ์ธก์œผ๋กœ 8๋น„ํŠธ๋ฅผ ์ˆœ์„œ๋Œ€๋กœ ํ™•์ธํ•ด์„œ ์ ์„ ์ฐ์–ด์„œ ๋ฌธ์ž๋ฅผ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค.
To summarize, the process involves checking 8 bits in order from left to right across the first eight lines and outputting characters by plotting points.

โœ”๏ธ ์ ˆ์ „ ๋ฐ ๋Œ€๊ธฐ์ƒํƒœ / Power Saving and Standby Modes

1)__asm_ ์–ด์…ˆ๋ธ”๋Ÿฌ ์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ํ‚ค์›Œ๋“œ์ž…๋‹ˆ๋‹ค.
__asm is a keyword used for assembler code.

2)__volatile__ hlt๋ช…๋ น์–ด๋ฅผ ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์‚ญ์ œํ•˜์ง€ ๋ชปํ•˜๊ฒŒ ๋ง‰๋Š” ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค.
__volatile__ prevents the compiler from removing the hlt instruction.

3)hlt๋Š” ๋‹ค์Œ ์‹ ํ˜ธ (์ธํ„ฐ๋ŸฝํŠธ) ์˜ฌ๋•Œ ๊นŒ์ง€ ๋Œ€๊ธฐ์ƒํƒœ๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
The HLT instruction sets the processor to a waiting state until the next signal (interrupt) arrives.

    while (1) {
        __asm__ __volatile__("hlt");
    }

๐Ÿ‘‰๏ธ ์ปดํŒŒ์ผ

# 1. ๋ถ€ํŠธ์„นํ„ฐ ๋ฐ ๋ณดํ˜ธ๋ชจ๋“œ ์ง„์ž…๋ถ€ ์ปดํŒŒ์ผ
nasm -f bin boot.asm -o boot.bin
nasm -f elf32 sector2.asm -o sector2.o

# 2. ์ƒˆ๋กœ ์ˆ˜์ •ํ•œ kernel.c ์ปดํŒŒ์ผ
gcc -m32 -c kernel.c -o kernel.o -nostdlib -fno-builtin -fno-stack-protector -fno-pic -fno-PIE

# 3. ํ•˜๋‚˜์˜ ๋ฐ”์ด๋„ˆ๋ฆฌ๋กœ ๊ฒฐํ•ฉ
ld -m elf_i386 -Ttext 0x8000 -e start -o sector2.bin sector2.o kernel.o --oformat binary

# 4. ์ด๋ฏธ์ง€ ์ƒ์„ฑ ๋ฐ ์‹คํ–‰
cat boot.bin sector2.bin > temp.bin
dd if=temp.bin of=os.img bs=512 count=2880 conv=sync
qemu-system-x86_64 -drive file=os.img,format=raw,if=floppy -boot a

Leave a Reply