일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 | 31 |
- Gundam
- 맛집 추천
- rg
- 맛집
- 30일
- 운영체제 제작
- project euler
- 운영체제
- OS 제작
- os 만들기
- OS
- 프라모델
- 건담
- 쉽게 배우는 운영체제 연습문제
- 쉽게 배우는 운영체제 풀이
- 건담 프라모델
- 운영체제 정리
- Project Euler 해답
- OS강의
- 쉽게 배우는 운영체제 솔루션
- 쉽게 배우는 운영체제
- OS 강의
- OS 구조와 원리
- 운영체제 만들기
- 건담 엑스포
- 건프라
- hg
- OS 그래픽 처리
- 운영체제 문제 풀이
- Project Euler Problem
- Today
- Total
밤색모자이크의 개발이야기
6일차. 분할 컴파일과 인터럽트 처리 본문
안녕하세요. 밤색모자이크입니다.
6일차에는 소스코드가 많이 길어져서 이것을 분할하는 것부터 합니다.
분할을 한 뒤에 인터럽트 처리를 하게 되는데, 키보드 인터럽트는 보입니다. 아쉽게도 마우스 인터럽트는 안되네요 ㅜㅜ
책에서는 자세히 설명하지만, 저는 분할과 인터럽트 부분을 다 통합한 부분만 보여드리겠습니다.
PIC (Programmable Interrupt Controller) :설정가능한 인터럽트 컨트롤러로써, 인터럽트를 관리할 수 있습니다.
IMR (Interrupt Mask Registier) : 인터럽트를 막아놓은 레지스터, 이 레지스터가 설정되어있으면 인터럽트를 무시합니다.
ICW (Intial Control Word) : 초기화 제어 데이터
개발환경
운영체제 : Windows10
텍스트 편집기 : Atom
PC 에뮬레이터 : QEMU
소스코드
수정된 파일
bootpack.c : 기존의 소소코드에서 그림 기능과 descriptor table 관련 기능을 분리
Makefile : 분리된 소스코드 컴파일 규칙 수정 및 중복 제거
naskfunc.nas : 인터럽트 관련 함수 추가
추가된 파일
bootpack.h : 분리 소스코드를 묶어주고, 중복제거를 위해 헤더파일을 추가
dsctbl.c : descriptor table 관련 함수들만 따로 작성하여 추가
graphic.c : 그래픽 관련 함수들만 따로 작성하여 추가
int.c : 인터럽트 관련 함수 추가
bootpack.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | /* asmhead.nas */ struct BOOTINFO { char cyls; char leds; char vmode; char reserve; short scrnx, scrny; char *vram; }; #define ADR_BOOTINFO 0x00000ff0 /* naskfunc.nas */ void io_hlt(void); void io_cli(void); void io_sti(void); void io_out8(int port, int data); int io_load_eflags(void); void io_store_eflags(int eflags); void load_gdtr(int limit, int addr); void load_idtr(int limit, int addr); void asm_inthandler21(void); void asm_inthandler2c(void); /* graphic.c */ void init_palette(void); void set_palette(int start, int end, unsigned char *rgb); void boxfill8(unsigned char *vram, int xsize, unsigned char c, int x0, int y0, int x1, int y1); void init_screen8(char *vram, int x, int y); void putfont8(char *vram, int xsize, int x, int y, char c, char *font); void putfonts8_asc(char *vram, int xsize, int x, int y, char c, unsigned char *s); void init_mouse_cursor8(char *mouse, char bc); void putblock8_8(char *vram, int vxsize, int pxsize, int pysize, int px0, int py0, char *buf, int bxsize); #define COL8_000000 0 #define COL8_FF0000 1 #define COL8_00FF00 2 #define COL8_FFFF00 3 #define COL8_0000FF 4 #define COL8_FF00FF 5 #define COL8_00FFFF 6 #define COL8_FFFFFF 7 #define COL8_C6C6C6 8 #define COL8_840000 9 #define COL8_008400 10 #define COL8_848400 11 #define COL8_000084 12 #define COL8_840084 13 #define COL8_008484 14 #define COL8_848484 15 /* dsctbl.c */ struct SEGMENT_DESCRIPTOR { short limit_low, base_low; char base_mid, access_right; char limit_high, base_high; }; struct GATE_DESCRIPTOR { short offset_low, selector; char dw_count, access_right; short offset_high; }; void init_gdtidt(void); void set_segmdesc(struct SEGMENT_DESCRIPTOR *sd, unsigned int limit, int base, int ar); void set_gatedesc(struct GATE_DESCRIPTOR *gd, int offset, int selector, int ar); #define ADR_IDT 0x0026f800 #define LIMIT_IDT 0x000007ff #define ADR_GDT 0x00270000 #define LIMIT_GDT 0x0000ffff #define ADR_BOTPAK 0x00280000 #define LIMIT_BOTPAK 0x0007ffff #define AR_DATA32_RW 0x4092 #define AR_CODE32_ER 0x409a #define AR_INTGATE32 0x008e /* int.c */ void init_pic(void); void inthandler21(int *esp); void inthandler2c(int *esp); #define PIC0_ICW1 0x0020 #define PIC0_OCW2 0x0020 #define PIC0_IMR 0x0021 #define PIC0_ICW2 0x0021 #define PIC0_ICW3 0x0021 #define PIC0_ICW4 0x0021 #define PIC1_ICW1 0x00a0 #define PIC1_OCW2 0x00a0 #define PIC1_IMR 0x00a1 #define PIC1_ICW2 0x00a1 #define PIC1_ICW3 0x00a1 #define PIC1_ICW4 0x00a1 |
기존의 주소라던가 항목들을 전부 정의해서 변수로써 설정했습니다.
따라서, 여기서만 상수 변경을 하면 나머지 파일에도 적용됩니다.
bootpack.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | #include "bootpack.h" #include <stdio.h> void HariMain(void) { struct BOOTINFO *binfo = (struct BOOTINFO *) ADR_BOOTINFO; char s[40], mcursor[256]; int mx, my; init_gdtidt(); init_pic(); io_sti(); /* IDT/PIC의 초기화가 끝났으므로 CPU의 인터럽트 금지를 해제 */ init_palette(); init_screen8(binfo->vram, binfo->scrnx, binfo->scrny); mx = (binfo->scrnx - 16) / 2; /* 화면 중앙이 되도록 좌표 계산 */ my = (binfo->scrny - 28 - 16) / 2; init_mouse_cursor8(mcursor, COL8_008484); putblock8_8(binfo->vram, binfo->scrnx, 16, 16, mx, my, mcursor, 16); sprintf(s, "(%d, %d)", mx, my); putfonts8_asc(binfo->vram, binfo->scrnx, 0, 0, COL8_FFFFFF, s); putfonts8_asc(binfo->vram, binfo->scrnx, 30, 30, COL8_FFFFFF, "Hi, Chestnut Mosaic OS"); io_out8(PIC0_IMR, 0xf9); /* PIC1와 키보드를 허가(11111001) */ io_out8(PIC1_IMR, 0xef); /* 마우스를 허가(11101111) */ for (;;) { io_hlt(); } } |
원래 300줄이 넘는 소스코드 파일이었는데, 메인만 남기고 전부 빠졌습니다.
dsctbl.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | /* GDT나 IDT등의 descriptor table 관계 */ #include "bootpack.h" void init_gdtidt(void) { struct SEGMENT_DESCRIPTOR *gdt = (struct SEGMENT_DESCRIPTOR *) ADR_GDT; struct GATE_DESCRIPTOR *idt = (struct GATE_DESCRIPTOR *) ADR_IDT; int i; /* GDT의 초기화 */ for (i = 0; i <= LIMIT_GDT / 8; i++) { set_segmdesc(gdt + i, 0, 0, 0); } set_segmdesc(gdt + 1, 0xffffffff, 0x00000000, AR_DATA32_RW); set_segmdesc(gdt + 2, LIMIT_BOTPAK, ADR_BOTPAK, AR_CODE32_ER); load_gdtr(LIMIT_GDT, ADR_GDT); /* IDT의 초기화 */ for (i = 0; i <= LIMIT_IDT / 8; i++) { set_gatedesc(idt + i, 0, 0, 0); } load_idtr(LIMIT_IDT, ADR_IDT); /* IDT의 설정 */ set_gatedesc(idt + 0x21, (int) asm_inthandler21, 2 * 8, AR_INTGATE32); set_gatedesc(idt + 0x2c, (int) asm_inthandler2c, 2 * 8, AR_INTGATE32); return; } void set_segmdesc(struct SEGMENT_DESCRIPTOR *sd, unsigned int limit, int base, int ar) { if (limit > 0xfffff) { ar |= 0x8000; /* G_bit = 1 */ limit /= 0x1000; } sd->limit_low = limit & 0xffff; sd->base_low = base & 0xffff; sd->base_mid = (base >> 16) & 0xff; sd->access_right = ar & 0xff; sd->limit_high = ((limit >> 16) & 0x0f) | ((ar >> 8) & 0xf0); sd->base_high = (base >> 24) & 0xff; return; } void set_gatedesc(struct GATE_DESCRIPTOR *gd, int offset, int selector, int ar) { gd->offset_low = offset & 0xffff; gd->selector = selector; gd->dw_count = (ar >> 8) & 0xff; gd->access_right = ar & 0xff; gd->offset_high = (offset >> 16) & 0xffff; return; } |
descriptor table 관련 함수들만 정리하였고, bootpack.h 파일은 붙였습니다.
graphic.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 | /* 그래픽 처리 관계 */ #include "bootpack.h" void init_palette(void) { static unsigned char table_rgb[16 * 3] = { 0x00, 0x00, 0x00, /* 0:흑 */ 0xff, 0x00, 0x00, /* 1:밝은 빨강 */ 0x00, 0xff, 0x00, /* 2:밝은 초록 */ 0xff, 0xff, 0x00, /* 3:밝은 황색 */ 0x00, 0x00, 0xff, /* 4:밝은 파랑 */ 0xff, 0x00, 0xff, /* 5:밝은 보라색 */ 0x00, 0xff, 0xff, /* 6:밝은 물색 */ 0xff, 0xff, 0xff, /* 7:흰색 */ 0xc6, 0xc6, 0xc6, /* 8:밝은 회색 */ 0x84, 0x00, 0x00, /* 9:어두운 빨강 */ 0x00, 0x84, 0x00, /* 10:어두운 초록 */ 0x84, 0x84, 0x00, /* 11:어두운 황색 */ 0x00, 0x00, 0x84, /* 12:어두운 파랑 */ 0x84, 0x00, 0x84, /* 13:어두운 보라색 */ 0x00, 0x84, 0x84, /* 14:어두운 물색 */ 0x84, 0x84, 0x84 /* 15:어두운 회색 */ }; set_palette(0, 15, table_rgb); return; /* static char 명령은 데이터 밖에 사용할 수 없지만 DB명령에 상당 */ } void set_palette(int start, int end, unsigned char *rgb) { int i, eflags; eflags = io_load_eflags(); /* 인터럽트 허가 플래그의 값을 기록한다 */ io_cli(); /* 허가 플래그를 0으로 해 인터럽트 금지로 한다 */ io_out8(0x03c8, start); for (i = start; i <= end; i++) { io_out8(0x03c9, rgb[0] / 4); io_out8(0x03c9, rgb[1] / 4); io_out8(0x03c9, rgb[2] / 4); rgb += 3; } io_store_eflags(eflags); /* 인터럽트 허가 플래그를 원래대로 되돌린다 */ return; } void boxfill8(unsigned char *vram, int xsize, unsigned char c, int x0, int y0, int x1, int y1) { int x, y; for (y = y0; y <= y1; y++) { for (x = x0; x <= x1; x++) vram[y * xsize + x] = c; } return; } void init_screen8(char *vram, int x, int y) { boxfill8(vram, x, COL8_008484, 0, 0, x - 1, y - 29); boxfill8(vram, x, COL8_C6C6C6, 0, y - 28, x - 1, y - 28); boxfill8(vram, x, COL8_FFFFFF, 0, y - 27, x - 1, y - 27); boxfill8(vram, x, COL8_C6C6C6, 0, y - 26, x - 1, y - 1); boxfill8(vram, x, COL8_FFFFFF, 3, y - 24, 59, y - 24); boxfill8(vram, x, COL8_FFFFFF, 2, y - 24, 2, y - 4); boxfill8(vram, x, COL8_848484, 3, y - 4, 59, y - 4); boxfill8(vram, x, COL8_848484, 59, y - 23, 59, y - 5); boxfill8(vram, x, COL8_000000, 2, y - 3, 59, y - 3); boxfill8(vram, x, COL8_000000, 60, y - 24, 60, y - 3); boxfill8(vram, x, COL8_848484, x - 47, y - 24, x - 4, y - 24); boxfill8(vram, x, COL8_848484, x - 47, y - 23, x - 47, y - 4); boxfill8(vram, x, COL8_FFFFFF, x - 47, y - 3, x - 4, y - 3); boxfill8(vram, x, COL8_FFFFFF, x - 3, y - 24, x - 3, y - 3); return; } void putfont8(char *vram, int xsize, int x, int y, char c, char *font) { int i; char *p, d /* data */; for (i = 0; i < 16; i++) { p = vram + (y + i) * xsize + x; d = font[i]; if ((d & 0x80) != 0) { p[0] = c; } if ((d & 0x40) != 0) { p[1] = c; } if ((d & 0x20) != 0) { p[2] = c; } if ((d & 0x10) != 0) { p[3] = c; } if ((d & 0x08) != 0) { p[4] = c; } if ((d & 0x04) != 0) { p[5] = c; } if ((d & 0x02) != 0) { p[6] = c; } if ((d & 0x01) != 0) { p[7] = c; } } return; } void putfonts8_asc(char *vram, int xsize, int x, int y, char c, unsigned char *s) { extern char hankaku[4096]; for (; *s != 0x00; s++) { putfont8(vram, xsize, x, y, c, hankaku + *s * 16); x += 8; } return; } void init_mouse_cursor8(char *mouse, char bc) /* 마우스 커서를 준비(16 x16) */ { static char cursor[16][16] = { "**************..", "*OOOOOOOOOOO*...", "*OOOOOOOOOO*....", "*OOOOOOOOO*.....", "*OOOOOOOO*......", "*OOOOOOO*.......", "*OOOOOOO*.......", "*OOOOOOOO*......", "*OOOO**OOO*.....", "*OOO*..*OOO*....", "*OO*....*OOO*...", "*O*......*OOO*..", "**........*OOO*.", "*..........*OOO*", "............*OO*", ".............***" }; int x, y; for (y = 0; y < 16; y++) { for (x = 0; x < 16; x++) { if (cursor[y][x] == '*') { mouse[y * 16 + x] = COL8_000000; } if (cursor[y][x] == 'O') { mouse[y * 16 + x] = COL8_FFFFFF; } if (cursor[y][x] == '.') { mouse[y * 16 + x] = bc; } } } return; } void putblock8_8(char *vram, int vxsize, int pxsize, int pysize, int px0, int py0, char *buf, int bxsize) { int x, y; for (y = 0; y < pysize; y++) { for (x = 0; x < pxsize; x++) { vram[(py0 + y) * vxsize + (px0 + x)] = buf[y * bxsize + x]; } } return; } |
그래픽 관련 함수들만 정리해서 bootpack.h 파일을 붙였습니다.
naskfunc.nas
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 | ; naskfunc ; TAB=4 [FORMAT "WCOFF"] ; 오브젝트 파일을 만드는 모드 [INSTRSET "i486p"] ; 486명령까지 사용하고 싶다고 하는 기술 [BITS 32] ; 32비트 모드용의 기계어를 만들게 한다 [FILE "naskfunc.nas"] ; 원시 파일명 정보 GLOBAL _io_hlt, _io_cli, _io_sti, io_stihlt GLOBAL _io_in8, _io_in16, _io_in32 GLOBAL _io_out8, _io_out16, _io_out32 GLOBAL _io_load_eflags, _io_store_eflags GLOBAL _load_gdtr, _load_idtr GLOBAL _asm_inthandler21, _asm_inthandler2c EXTERN _inthandler21, _inthandler2c [SECTION .text] _io_hlt: ; void io_hlt(void); HLT RET _io_cli: ; void io_cli(void); CLI RET _io_sti: ; void io_sti(void); STI RET _io_stihlt: ; void io_stihlt(void); STI HLT RET _io_in8: ; int io_in8(int port); MOV EDX,[ESP+4] ; port MOV EAX,0 IN AL,DX RET _io_in16: ; int io_in16(int port); MOV EDX,[ESP+4] ; port MOV EAX,0 IN AX,DX RET _io_in32: ; int io_in32(int port); MOV EDX,[ESP+4] ; port IN EAX,DX RET _io_out8: ; void io_out8(int port, int data); MOV EDX,[ESP+4] ; port MOV AL,[ESP+8] ; data OUT DX,AL RET _io_out16: ; void io_out16(int port, int data); MOV EDX,[ESP+4] ; port MOV EAX,[ESP+8] ; data OUT DX,AX RET _io_out32: ; void io_out32(int port, int data); MOV EDX,[ESP+4] ; port MOV EAX,[ESP+8] ; data OUT DX,EAX RET _io_load_eflags: ; int io_load_eflags(void); PUSHFD ; PUSH EFLAGS 라고 하는 의미 POP EAX RET _io_store_eflags: ; void io_store_eflags(int eflags); MOV EAX,[ESP+4] PUSH EAX POPFD ; POP EFLAGS 라고 하는 의미 RET _load_gdtr: ; void load_gdtr(int limit, int addr); MOV AX,[ESP+4] ; limit MOV [ESP+6],AX LGDT [ESP+6] RET _load_idtr: ; void load_idtr(int limit, int addr); MOV AX,[ESP+4] ; limit MOV [ESP+6],AX LIDT [ESP+6] RET _asm_inthandler21: PUSH ES PUSH DS PUSHAD MOV EAX,ESP PUSH EAX MOV AX,SS MOV DS,AX MOV ES,AX CALL _inthandler21 POP EAX POPAD POP DS POP ES IRETD _asm_inthandler2c: PUSH ES PUSH DS PUSHAD MOV EAX,ESP PUSH EAX MOV AX,SS MOV DS,AX MOV ES,AX CALL _inthandler2c POP EAX POPAD POP DS POP ES IRETD |
인터럽트 관련 함수를 추가했습니다.
이때 보시면, 인터럽트를 스택 구조를 활용하여 처리했습니다.
int.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | /* 인터럽트 관계 */ #include "bootpack.h" void init_pic(void) /* PIC의 초기화 */ { io_out8(PIC0_IMR, 0xff ); /* 모든 인터럽트를 받아들이지 않는다 */ io_out8(PIC1_IMR, 0xff ); /* 모든 인터럽트를 받아들이지 않는다 */ io_out8(PIC0_ICW1, 0x11 ); /* edge trigger 모드 */ io_out8(PIC0_ICW2, 0x20 ); /* IRQ0-7은, INT20-27으로 받는다 */ io_out8(PIC0_ICW3, 1 << 2); /* PIC1는 IRQ2에서 접속 */ io_out8(PIC0_ICW4, 0x01 ); /* non buffer모드 */ io_out8(PIC1_ICW1, 0x11 ); /* edge trigger 모드 */ io_out8(PIC1_ICW2, 0x28 ); /* IRQ8-15는, INT28-2 f로 받는다 */ io_out8(PIC1_ICW3, 2 ); /* PIC1는 IRQ2에서 접속 */ io_out8(PIC1_ICW4, 0x01 ); /* non buffer모드 */ io_out8(PIC0_IMR, 0xfb ); /* 11111011 PIC1 이외는 모두 금지 */ io_out8(PIC1_IMR, 0xff ); /* 11111111 모든 인터럽트를 받아들이지 않는다 */ return; } void inthandler21(int *esp) /* PS/2 키보드로부터의 인터럽트 */ { struct BOOTINFO *binfo = (struct BOOTINFO *) ADR_BOOTINFO; boxfill8(binfo->vram, binfo->scrnx, COL8_000000, 0, 0, 32 * 8 - 1, 15); putfonts8_asc(binfo->vram, binfo->scrnx, 0, 0, COL8_FFFFFF, "INT 21 (IRQ-1) : PS/2 keyboard"); for (;;) { io_hlt(); } } void inthandler2c(int *esp) /* PS/2 마우스로부터의 인터럽트 */ { struct BOOTINFO *binfo = (struct BOOTINFO *) ADR_BOOTINFO; boxfill8(binfo->vram, binfo->scrnx, COL8_000000, 0, 0, 32 * 8 - 1, 15); putfonts8_asc(binfo->vram, binfo->scrnx, 0, 0, COL8_FFFFFF, "INT 2C (IRQ-12) : PS/2 mouse"); for (;;) { io_hlt(); } } |
인터럽트가 발생하면 화면에 뿌려주는 함수를 추가했습니다.
Makefile
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | OBJS_BOOTPACK = bootpack.obj naskfunc.obj hankaku.obj graphic.obj dsctbl.obj \ int.obj TOOLPATH = ../z_tools/ INCPATH = ../z_tools/haribote/ MAKE = $(TOOLPATH)make.exe -r NASK = $(TOOLPATH)nask.exe CC1 = $(TOOLPATH)cc1.exe -I$(INCPATH) -Os -Wall -quiet GAS2NASK = $(TOOLPATH)gas2nask.exe -a OBJ2BIM = $(TOOLPATH)obj2bim.exe MAKEFONT = $(TOOLPATH)makefont.exe BIN2OBJ = $(TOOLPATH)bin2obj.exe BIM2HRB = $(TOOLPATH)bim2hrb.exe RULEFILE = $(TOOLPATH)haribote/haribote.rul EDIMG = $(TOOLPATH)edimg.exe IMGTOL = $(TOOLPATH)imgtol.com COPY = copy DEL = del # 디폴트 동작 default : $(MAKE) img # 파일 생성 규칙 ipl10.bin : ipl10.nas Makefile $(NASK) ipl10.nas ipl10.bin ipl10.lst asmhead.bin : asmhead.nas Makefile $(NASK) asmhead.nas asmhead.bin asmhead.lst hankaku.bin : hankaku.txt Makefile $(MAKEFONT) hankaku.txt hankaku.bin hankaku.obj : hankaku.bin Makefile $(BIN2OBJ) hankaku.bin hankaku.obj _hankaku bootpack.bim : $(OBJS_BOOTPACK) Makefile $(OBJ2BIM) @$(RULEFILE) out:bootpack.bim stack:3136k map:bootpack.map \ $(OBJS_BOOTPACK) # 3MB+64KB=3136KB bootpack.hrb : bootpack.bim Makefile $(BIM2HRB) bootpack.bim bootpack.hrb 0 haribote.sys : asmhead.bin bootpack.hrb Makefile copy /B asmhead.bin+bootpack.hrb haribote.sys haribote.img : ipl10.bin haribote.sys Makefile $(EDIMG) imgin:../z_tools/fdimg0at.tek \ wbinimg src:ipl10.bin len:512 from:0 to:0 \ copy from:haribote.sys to:@: \ imgout:haribote.img # 일반 규칙 %.gas : %.c Makefile $(CC1) -o $*.gas $*.c %.nas : %.gas Makefile $(GAS2NASK) $*.gas $*.nas %.obj : %.nas Makefile $(NASK) $*.nas $*.obj $*.lst # 커맨드 img : $(MAKE) haribote.img run : $(MAKE) img $(COPY) haribote.img ..\z_tools\qemu\fdimage0.bin $(MAKE) -C ../z_tools/qemu install : $(MAKE) img $(IMGTOL) w a: haribote.img clean : -$(DEL) *.bin -$(DEL) *.lst -$(DEL) *.obj -$(DEL) bootpack.map -$(DEL) bootpack.bim -$(DEL) bootpack.hrb -$(DEL) haribote.sys src_only : $(MAKE) clean -$(DEL) haribote.img |
기존의 규칙을 수정하고, 반복된 작업을 제거했습니다.
계속 코드가 커지다 보니까 소스코드 양도 점점 늘어나네요.
이 포스팅에 올려진 코드들이 전부가 아닙니다. 수정되고 추가된 파일들만 추가했습니다.
기존의 코드들을 보고 싶으시면 다음 링크를 이용하세요.
http://godrjsmgl.tistory.com/66
실행
실행하기 전 파일 목록입니다.
이제 컴파일화면이 점점 늘어나네요.
컴파일 후 파일목록입니다.
결과
실행하면 위 화면 처럼 실행됩니다.
이 상태에서 키보드를 눌러보면 아래와 같은 한 줄이 추가됩니다.
키보드 인터럽트 처리를 제대로 하게 되면 위와 같은 화면이 나타납니다.
마우스도 나타나야하는데 아쉽게도 이번에는 안되네요.
참고 자료
OS 구조와 원리, 카와이 히데미 저, 한빛미디어 출판
링크 : http://www.hanbit.co.kr/store/books/look.php?p_code=B9833754652
링크 : http://godrjsmgl.tistory.com/66
'Embedded > OS제작 with OS구조와원리' 카테고리의 다른 글
8일차. 마우스 제어와 32비트 모드 전환 (4) | 2017.08.08 |
---|---|
7일차. FIFO와 마우스 제어 (0) | 2017.08.06 |
5일차. 문자 표시와 마우스를 위한 GDT/IDT 초기화 (0) | 2017.07.10 |
4일차. C언어와 화면 표시 - (3) OS 화면 구성 (0) | 2017.07.09 |
4일차. C언어와 화면 표시 - (2) 사각형 띄우기 (0) | 2017.07.09 |