敲擊鍵盤有兩個方面的含義:動作和內容。
.
├── a.img
├── boot
│ ├── boot.asm
│ ├── include
│ │ ├── fat12hdr.inc
│ │ ├── load.inc
│ │ └── pm.inc
│ └── loader.asm
├── include
│ ├── const.h
│ ├── global.h
│ ├── keyboard.h
│ ├── keymap.h
│ ├── proc.h
│ ├── protect.h
│ ├── proto.h
│ ├── sconst.inc
│ ├── string.h
│ └── type.h
├── kernel
│ ├── clock.c
│ ├── global.c
│ ├── i8259.c
│ ├── kernel.asm
│ ├── keyboard.c
│ ├── main.c
│ ├── proc.c
│ ├── protect.c
│ ├── start.c
│ ├── syscall.asm
│ └── tty.c
└── lib
├── kliba.asm
├── klib.c
└── string.asm
- 動作可分為三類:按下、保持按住的狀態、放開
- 內容則是鍵盤上不同的鍵。
- 當一個鍵被按下或者保持住按下時,將會產生 Make Code,當鍵盤彈起時,產生 Break Code。
- 除了 Pause 鍵之外,每個按鍵都對應一個 Make Code 和一個 Break Code。
當 8048 檢測到一個鍵的動作後,會把相應的掃描碼發送給 8042,8042會把它轉換成相應的 Scan code set1 掃描碼,並將其放置在輸入緩衝區中,然後 8042 告訴 8259A 產生中斷(IRQ1)。如果此時鍵盤又有新的鍵被按下,8042 將不再接收,一直到緩衝區被清空,8042 才會收到更多的掃描碼。
程式碼
include/const.h
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
const.h
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Forrest Yu, 2005
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
#ifndef _ORANGES_CONST_H_
#define _ORANGES_CONST_H_
/* EXTERN */
#define EXTERN extern /* EXTERN is defined as extern except in global.c */
/* 函數類型 */
#define PUBLIC /* PUBLIC is the opposite of PRIVATE */
#define PRIVATE static /* PRIVATE x limits the scope of x */
/* Color */
/*
* e.g. MAKE_COLOR(BLUE, RED)
* MAKE_COLOR(BLACK, RED) | BRIGHT
* MAKE_COLOR(BLACK, RED) | BRIGHT | FLASH
*/
#define BLACK 0x0 /* 0000 */
#define WHITE 0x7 /* 0111 */
#define RED 0x4 /* 0100 */
#define GREEN 0x2 /* 0010 */
#define BLUE 0x1 /* 0001 */
#define FLASH 0x80 /* 1000 0000 */
#define BRIGHT 0x08 /* 0000 1000 */
#define MAKE_COLOR(x,y) (x | y) /* MAKE_COLOR(Background,Foreground) */
/* GDT 和 IDT 中描述符的個數 */
#define GDT_SIZE 128
#define IDT_SIZE 256
/* 權限 */
#define PRIVILEGE_KRNL 0
#define PRIVILEGE_TASK 1
#define PRIVILEGE_USER 3
/* RPL */
#define RPL_KRNL SA_RPL0
#define RPL_TASK SA_RPL1
#define RPL_USER SA_RPL3
/* 8259A interrupt controller ports. */
#define INT_M_CTL 0x20 /* I/O port for interrupt controller <Master> */
#define INT_M_CTLMASK 0x21 /* setting bits in this port disables ints <Master> */
#define INT_S_CTL 0xA0 /* I/O port for second interrupt controller <Slave> */
#define INT_S_CTLMASK 0xA1 /* setting bits in this port disables ints <Slave> */
/* 8253/8254 PIT (Programmable Interval Timer) */
#define TIMER0 0x40 /* I/O port for timer channel 0 */
#define TIMER_MODE 0x43 /* I/O port for timer mode control */
#define RATE_GENERATOR 0x34 /* 00-11-010-0 :
* Counter0 - LSB then MSB - rate generator - binary
*/
#define TIMER_FREQ 1193182L/* clock frequency for timer in PC and AT */
#define HZ 100 /* clock freq (software settable on IBM-PC) */
/* AT keyboard */
/* 8042 ports */
#define KB_DATA 0x60 /* I/O port for keyboard data
Read : Read Output Buffer
Write: Write Input Buffer(8042 Data&8048 Command) */
#define KB_CMD 0x64 /* I/O port for keyboard command
Read : Read Status Register
Write: Write Input Buffer(8042 Command) */
/* Hardware interrupts */
#define NR_IRQ 16 /* Number of IRQs */
#define CLOCK_IRQ 0
#define KEYBOARD_IRQ 1
#define CASCADE_IRQ 2 /* cascade enable for 2nd AT controller */
#define ETHER_IRQ 3 /* default ethernet interrupt vector */
#define SECONDARY_IRQ 3 /* RS232 interrupt vector for port 2 */
#define RS232_IRQ 4 /* RS232 interrupt vector for port 1 */
#define XT_WINI_IRQ 5 /* xt winchester */
#define FLOPPY_IRQ 6 /* floppy disk */
#define PRINTER_IRQ 7
#define AT_WINI_IRQ 14 /* at winchester */
/* system call */
#define NR_SYS_CALL 1
#endif /* _ORANGES_CONST_H_ */
include/keyboard.h
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
keyboard.h
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Forrest Yu, December, 2003
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
#ifndef _ORANGES_KEYBOARD_H_
#define _ORANGES_KEYBOARD_H_
/************************************************************************/
/* Macros Declaration */
/************************************************************************/
#define KB_IN_BYTES 32 /* size of keyboard input buffer */
#define MAP_COLS 3 /* Number of columns in keymap */
#define NR_SCAN_CODES 0x80 /* Number of scan codes (rows in keymap) */
#define FLAG_BREAK 0x0080 /* Break Code */
#define FLAG_EXT 0x0100 /* Normal function keys */
#define FLAG_SHIFT_L 0x0200 /* Shift key */
#define FLAG_SHIFT_R 0x0400 /* Shift key */
#define FLAG_CTRL_L 0x0800 /* Control key */
#define FLAG_CTRL_R 0x1000 /* Control key */
#define FLAG_ALT_L 0x2000 /* Alternate key */
#define FLAG_ALT_R 0x4000 /* Alternate key */
#define FLAG_PAD 0x8000 /* keys in num pad */
#define MASK_RAW 0x01FF /* raw key value = code passed to tty & MASK_RAW
the value can be found either in the keymap column 0
or in the list below */
/* Special keys */
#define ESC (0x01 + FLAG_EXT) /* Esc */
#define TAB (0x02 + FLAG_EXT) /* Tab */
#define ENTER (0x03 + FLAG_EXT) /* Enter */
#define BACKSPACE (0x04 + FLAG_EXT) /* BackSpace */
#define GUI_L (0x05 + FLAG_EXT) /* L GUI */
#define GUI_R (0x06 + FLAG_EXT) /* R GUI */
#define APPS (0x07 + FLAG_EXT) /* APPS */
/* Shift, Ctrl, Alt */
#define SHIFT_L (0x08 + FLAG_EXT) /* L Shift */
#define SHIFT_R (0x09 + FLAG_EXT) /* R Shift */
#define CTRL_L (0x0A + FLAG_EXT) /* L Ctrl */
#define CTRL_R (0x0B + FLAG_EXT) /* R Ctrl */
#define ALT_L (0x0C + FLAG_EXT) /* L Alt */
#define ALT_R (0x0D + FLAG_EXT) /* R Alt */
/* Lock keys */
#define CAPS_LOCK (0x0E + FLAG_EXT) /* Caps Lock */
#define NUM_LOCK (0x0F + FLAG_EXT) /* Number Lock */
#define SCROLL_LOCK (0x10 + FLAG_EXT) /* Scroll Lock */
/* Function keys */
#define F1 (0x11 + FLAG_EXT) /* F1 */
#define F2 (0x12 + FLAG_EXT) /* F2 */
#define F3 (0x13 + FLAG_EXT) /* F3 */
#define F4 (0x14 + FLAG_EXT) /* F4 */
#define F5 (0x15 + FLAG_EXT) /* F5 */
#define F6 (0x16 + FLAG_EXT) /* F6 */
#define F7 (0x17 + FLAG_EXT) /* F7 */
#define F8 (0x18 + FLAG_EXT) /* F8 */
#define F9 (0x19 + FLAG_EXT) /* F9 */
#define F10 (0x1A + FLAG_EXT) /* F10 */
#define F11 (0x1B + FLAG_EXT) /* F11 */
#define F12 (0x1C + FLAG_EXT) /* F12 */
/* Control Pad */
#define PRINTSCREEN (0x1D + FLAG_EXT) /* Print Screen */
#define PAUSEBREAK (0x1E + FLAG_EXT) /* Pause/Break */
#define INSERT (0x1F + FLAG_EXT) /* Insert */
#define DELETE (0x20 + FLAG_EXT) /* Delete */
#define HOME (0x21 + FLAG_EXT) /* Home */
#define END (0x22 + FLAG_EXT) /* End */
#define PAGEUP (0x23 + FLAG_EXT) /* Page Up */
#define PAGEDOWN (0x24 + FLAG_EXT) /* Page Down */
#define UP (0x25 + FLAG_EXT) /* Up */
#define DOWN (0x26 + FLAG_EXT) /* Down */
#define LEFT (0x27 + FLAG_EXT) /* Left */
#define RIGHT (0x28 + FLAG_EXT) /* Right */
/* ACPI keys */
#define POWER (0x29 + FLAG_EXT) /* Power */
#define SLEEP (0x2A + FLAG_EXT) /* Sleep */
#define WAKE (0x2B + FLAG_EXT) /* Wake Up */
/* Num Pad */
#define PAD_SLASH (0x2C + FLAG_EXT) /* / */
#define PAD_STAR (0x2D + FLAG_EXT) /* * */
#define PAD_MINUS (0x2E + FLAG_EXT) /* - */
#define PAD_PLUS (0x2F + FLAG_EXT) /* + */
#define PAD_ENTER (0x30 + FLAG_EXT) /* Enter */
#define PAD_DOT (0x31 + FLAG_EXT) /* . */
#define PAD_0 (0x32 + FLAG_EXT) /* 0 */
#define PAD_1 (0x33 + FLAG_EXT) /* 1 */
#define PAD_2 (0x34 + FLAG_EXT) /* 2 */
#define PAD_3 (0x35 + FLAG_EXT) /* 3 */
#define PAD_4 (0x36 + FLAG_EXT) /* 4 */
#define PAD_5 (0x37 + FLAG_EXT) /* 5 */
#define PAD_6 (0x38 + FLAG_EXT) /* 6 */
#define PAD_7 (0x39 + FLAG_EXT) /* 7 */
#define PAD_8 (0x3A + FLAG_EXT) /* 8 */
#define PAD_9 (0x3B + FLAG_EXT) /* 9 */
#define PAD_UP PAD_8 /* Up */
#define PAD_DOWN PAD_2 /* Down */
#define PAD_LEFT PAD_4 /* Left */
#define PAD_RIGHT PAD_6 /* Right */
#define PAD_HOME PAD_7 /* Home */
#define PAD_END PAD_1 /* End */
#define PAD_PAGEUP PAD_9 /* Page Up */
#define PAD_PAGEDOWN PAD_3 /* Page Down */
#define PAD_INS PAD_0 /* Ins */
#define PAD_MID PAD_5 /* Middle key */
#define PAD_DEL PAD_DOT /* Del */
/************************************************************************/
/* Stucture Definition */
/************************************************************************/
/* Keyboard structure, 1 per console. */
typedef struct s_kb {
char* p_head; /* 指向緩衝區中下一個空閒位置 */
char* p_tail; /* 指向鍵盤任務應處理的字節 */
int count; /* 緩衝區中共有多少字節 */
char buf[KB_IN_BYTES]; /* 緩衝區 */
}KB_INPUT;
#endif /* _ORANGES_KEYBOARD_H_ */
include/keymap.h
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
keymap.h
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Forrest Yu, January, 2004
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/********************************************************************/
/* "scan code" <--> "key" map. */
/* It should be and can only be included by keyboard.c! */
/********************************************************************/
#ifndef _ORANGES_KEYMAP_H_
#define _ORANGES_KEYMAP_H_
/* Keymap for US MF-2 keyboard. */
u32 keymap[NR_SCAN_CODES * MAP_COLS] = {
/* scan-code !Shift Shift E0 XX */
/* ==================================================================== */
/* 0x00 - none */ 0, 0, 0,
/* 0x01 - ESC */ ESC, ESC, 0,
/* 0x02 - '1' */ '1', '!', 0,
/* 0x03 - '2' */ '2', '@', 0,
/* 0x04 - '3' */ '3', '#', 0,
/* 0x05 - '4' */ '4', '$', 0,
/* 0x06 - '5' */ '5', '%', 0,
/* 0x07 - '6' */ '6', '^', 0,
/* 0x08 - '7' */ '7', '&', 0,
/* 0x09 - '8' */ '8', '*', 0,
/* 0x0A - '9' */ '9', '(', 0,
/* 0x0B - '0' */ '0', ')', 0,
/* 0x0C - '-' */ '-', '_', 0,
/* 0x0D - '=' */ '=', '+', 0,
/* 0x0E - BS */ BACKSPACE, BACKSPACE, 0,
/* 0x0F - TAB */ TAB, TAB, 0,
/* 0x10 - 'q' */ 'q', 'Q', 0,
/* 0x11 - 'w' */ 'w', 'W', 0,
/* 0x12 - 'e' */ 'e', 'E', 0,
/* 0x13 - 'r' */ 'r', 'R', 0,
/* 0x14 - 't' */ 't', 'T', 0,
/* 0x15 - 'y' */ 'y', 'Y', 0,
/* 0x16 - 'u' */ 'u', 'U', 0,
/* 0x17 - 'i' */ 'i', 'I', 0,
/* 0x18 - 'o' */ 'o', 'O', 0,
/* 0x19 - 'p' */ 'p', 'P', 0,
/* 0x1A - '[' */ '[', '{', 0,
/* 0x1B - ']' */ ']', '}', 0,
/* 0x1C - CR/LF */ ENTER, ENTER, PAD_ENTER,
/* 0x1D - l. Ctrl */ CTRL_L, CTRL_L, CTRL_R,
/* 0x1E - 'a' */ 'a', 'A', 0,
/* 0x1F - 's' */ 's', 'S', 0,
/* 0x20 - 'd' */ 'd', 'D', 0,
/* 0x21 - 'f' */ 'f', 'F', 0,
/* 0x22 - 'g' */ 'g', 'G', 0,
/* 0x23 - 'h' */ 'h', 'H', 0,
/* 0x24 - 'j' */ 'j', 'J', 0,
/* 0x25 - 'k' */ 'k', 'K', 0,
/* 0x26 - 'l' */ 'l', 'L', 0,
/* 0x27 - ';' */ ';', ':', 0,
/* 0x28 - '\'' */ '\'', '"', 0,
/* 0x29 - '`' */ '`', '~', 0,
/* 0x2A - l. SHIFT */ SHIFT_L, SHIFT_L, 0,
/* 0x2B - '\' */ '\\', '|', 0,
/* 0x2C - 'z' */ 'z', 'Z', 0,
/* 0x2D - 'x' */ 'x', 'X', 0,
/* 0x2E - 'c' */ 'c', 'C', 0,
/* 0x2F - 'v' */ 'v', 'V', 0,
/* 0x30 - 'b' */ 'b', 'B', 0,
/* 0x31 - 'n' */ 'n', 'N', 0,
/* 0x32 - 'm' */ 'm', 'M', 0,
/* 0x33 - ',' */ ',', '<', 0,
/* 0x34 - '.' */ '.', '>', 0,
/* 0x35 - '/' */ '/', '?', PAD_SLASH,
/* 0x36 - r. SHIFT */ SHIFT_R, SHIFT_R, 0,
/* 0x37 - '*' */ '*', '*', 0,
/* 0x38 - ALT */ ALT_L, ALT_L, ALT_R,
/* 0x39 - ' ' */ ' ', ' ', 0,
/* 0x3A - CapsLock */ CAPS_LOCK, CAPS_LOCK, 0,
/* 0x3B - F1 */ F1, F1, 0,
/* 0x3C - F2 */ F2, F2, 0,
/* 0x3D - F3 */ F3, F3, 0,
/* 0x3E - F4 */ F4, F4, 0,
/* 0x3F - F5 */ F5, F5, 0,
/* 0x40 - F6 */ F6, F6, 0,
/* 0x41 - F7 */ F7, F7, 0,
/* 0x42 - F8 */ F8, F8, 0,
/* 0x43 - F9 */ F9, F9, 0,
/* 0x44 - F10 */ F10, F10, 0,
/* 0x45 - NumLock */ NUM_LOCK, NUM_LOCK, 0,
/* 0x46 - ScrLock */ SCROLL_LOCK, SCROLL_LOCK, 0,
/* 0x47 - Home */ PAD_HOME, '7', HOME,
/* 0x48 - CurUp */ PAD_UP, '8', UP,
/* 0x49 - PgUp */ PAD_PAGEUP, '9', PAGEUP,
/* 0x4A - '-' */ PAD_MINUS, '-', 0,
/* 0x4B - Left */ PAD_LEFT, '4', LEFT,
/* 0x4C - MID */ PAD_MID, '5', 0,
/* 0x4D - Right */ PAD_RIGHT, '6', RIGHT,
/* 0x4E - '+' */ PAD_PLUS, '+', 0,
/* 0x4F - End */ PAD_END, '1', END,
/* 0x50 - Down */ PAD_DOWN, '2', DOWN,
/* 0x51 - PgDown */ PAD_PAGEDOWN, '3', PAGEDOWN,
/* 0x52 - Insert */ PAD_INS, '0', INSERT,
/* 0x53 - Delete */ PAD_DOT, '.', DELETE,
/* 0x54 - Enter */ 0, 0, 0,
/* 0x55 - ??? */ 0, 0, 0,
/* 0x56 - ??? */ 0, 0, 0,
/* 0x57 - F11 */ F11, F11, 0,
/* 0x58 - F12 */ F12, F12, 0,
/* 0x59 - ??? */ 0, 0, 0,
/* 0x5A - ??? */ 0, 0, 0,
/* 0x5B - ??? */ 0, 0, GUI_L,
/* 0x5C - ??? */ 0, 0, GUI_R,
/* 0x5D - ??? */ 0, 0, APPS,
/* 0x5E - ??? */ 0, 0, 0,
/* 0x5F - ??? */ 0, 0, 0,
/* 0x60 - ??? */ 0, 0, 0,
/* 0x61 - ??? */ 0, 0, 0,
/* 0x62 - ??? */ 0, 0, 0,
/* 0x63 - ??? */ 0, 0, 0,
/* 0x64 - ??? */ 0, 0, 0,
/* 0x65 - ??? */ 0, 0, 0,
/* 0x66 - ??? */ 0, 0, 0,
/* 0x67 - ??? */ 0, 0, 0,
/* 0x68 - ??? */ 0, 0, 0,
/* 0x69 - ??? */ 0, 0, 0,
/* 0x6A - ??? */ 0, 0, 0,
/* 0x6B - ??? */ 0, 0, 0,
/* 0x6C - ??? */ 0, 0, 0,
/* 0x6D - ??? */ 0, 0, 0,
/* 0x6E - ??? */ 0, 0, 0,
/* 0x6F - ??? */ 0, 0, 0,
/* 0x70 - ??? */ 0, 0, 0,
/* 0x71 - ??? */ 0, 0, 0,
/* 0x72 - ??? */ 0, 0, 0,
/* 0x73 - ??? */ 0, 0, 0,
/* 0x74 - ??? */ 0, 0, 0,
/* 0x75 - ??? */ 0, 0, 0,
/* 0x76 - ??? */ 0, 0, 0,
/* 0x77 - ??? */ 0, 0, 0,
/* 0x78 - ??? */ 0, 0, 0,
/* 0x78 - ??? */ 0, 0, 0,
/* 0x7A - ??? */ 0, 0, 0,
/* 0x7B - ??? */ 0, 0, 0,
/* 0x7C - ??? */ 0, 0, 0,
/* 0x7D - ??? */ 0, 0, 0,
/* 0x7E - ??? */ 0, 0, 0,
/* 0x7F - ??? */ 0, 0, 0
};
/*
迴車鍵: 把光標移到第一列
換行鍵: 把光標前進到下一行
*/
/*====================================================================================*
Appendix: Scan code set 1
*====================================================================================*
KEY MAKE BREAK ----- KEY MAKE BREAK ----- KEY MAKE BREAK
--------------------------------------------------------------------------------------
A 1E 9E 9 0A 8A [ 1A 9A
B 30 B0 ` 29 89 INSERT E0,52 E0,D2
C 2E AE - 0C 8C HOME E0,47 E0,C7
D 20 A0 = 0D 8D PG UP E0,49 E0,C9
E 12 92 \ 2B AB DELETE E0,53 E0,D3
F 21 A1 BKSP 0E 8E END E0,4F E0,CF
G 22 A2 SPACE 39 B9 PG DN E0,51 E0,D1
H 23 A3 TAB 0F 8F U ARROW E0,48 E0,C8
I 17 97 CAPS 3A BA L ARROW E0,4B E0,CB
J 24 A4 L SHFT 2A AA D ARROW E0,50 E0,D0
K 25 A5 L CTRL 1D 9D R ARROW E0,4D E0,CD
L 26 A6 L GUI E0,5B E0,DB NUM 45 C5
M 32 B2 L ALT 38 B8 KP / E0,35 E0,B5
N 31 B1 R SHFT 36 B6 KP * 37 B7
O 18 98 R CTRL E0,1D E0,9D KP - 4A CA
P 19 99 R GUI E0,5C E0,DC KP + 4E CE
Q 10 19 R ALT E0,38 E0,B8 KP EN E0,1C E0,9C
R 13 93 APPS E0,5D E0,DD KP . 53 D3
S 1F 9F ENTER 1C 9C KP 0 52 D2
T 14 94 ESC 01 81 KP 1 4F CF
U 16 96 F1 3B BB KP 2 50 D0
V 2F AF F2 3C BC KP 3 51 D1
W 11 91 F3 3D BD KP 4 4B CB
X 2D AD F4 3E BE KP 5 4C CC
Y 15 95 F5 3F BF KP 6 4D CD
Z 2C AC F6 40 C0 KP 7 47 C7
0 0B 8B F7 41 C1 KP 8 48 C8
1 02 82 F8 42 C2 KP 9 49 C9
2 03 83 F9 43 C3 ] 1B 9B
3 04 84 F10 44 C4 ; 27 A7
4 05 85 F11 57 D7 ' 28 A8
5 06 86 F12 58 D8 , 33 B3
6 07 87 PRTSCRN E0,2A E0,B7 . 34 B4
E0,37 E0,AA
7 08 88 SCROLL 46 C6 / 35 B5
8 09 89 PAUSE E1,1D,45 -NONE-
E1,9D,C5
-----------------
ACPI Scan Codes:
-------------------------------------------
Key Make Code Break Code
-------------------------------------------
Power E0, 5E E0, DE
Sleep E0, 5F E0, DF
Wake E0, 63 E0, E3
-------------------------------
Windows Multimedia Scan Codes:
-------------------------------------------
Key Make Code Break Code
-------------------------------------------
Next Track E0, 19 E0, 99
Previous Track E0, 10 E0, 90
Stop E0, 24 E0, A4
Play/Pause E0, 22 E0, A2
Mute E0, 20 E0, A0
Volume Up E0, 30 E0, B0
Volume Down E0, 2E E0, AE
Media Select E0, 6D E0, ED
E-Mail E0, 6C E0, EC
Calculator E0, 21 E0, A1
My Computer E0, 6B E0, EB
WWW Search E0, 65 E0, E5
WWW Home E0, 32 E0, B2
WWW Back E0, 6A E0, EA
WWW Forward E0, 69 E0, E9
WWW Stop E0, 68 E0, E8
WWW Refresh E0, 67 E0, E7
WWW Favorites E0, 66 E0, E6
*=====================================================================================*/
#endif /* _ORANGES_KEYMAP_H_ */
include/proc.h
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
proc.h
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Forrest Yu, 2005
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
typedef struct s_stackframe { /* proc_ptr points here ↑ Low */
u32 gs; /* ┓ │ */
u32 fs; /* ┃ │ */
u32 es; /* ┃ │ */
u32 ds; /* ┃ │ */
u32 edi; /* ┃ │ */
u32 esi; /* ┣ pushed by save() │ */
u32 ebp; /* ┃ │ */
u32 kernel_esp; /* <- 'popad' will ignore it │ */
u32 ebx; /* ┃ ↑棧從高地址往低地址增長*/
u32 edx; /* ┃ │ */
u32 ecx; /* ┃ │ */
u32 eax; /* ┛ │ */
u32 retaddr; /* return address for assembly code save() │ */
u32 eip; /* ┓ │ */
u32 cs; /* ┃ │ */
u32 eflags; /* ┣ these are pushed by CPU during interrupt │ */
u32 esp; /* ┃ │ */
u32 ss; /* ┛ ┷High */
}STACK_FRAME;
typedef struct s_proc {
STACK_FRAME regs; /* process registers saved in stack frame */
u16 ldt_sel; /* gdt selector giving ldt base and limit */
DESCRIPTOR ldts[LDT_SIZE]; /* local descriptors for code and data */
int ticks; /* remained ticks */
int priority;
u32 pid; /* process id passed in from MM */
char p_name[16]; /* name of the process */
}PROCESS;
typedef struct s_task {
task_f initial_eip;
int stacksize;
char name[32];
}TASK;
/* Number of tasks */
#define NR_TASKS 4
/* stacks of tasks */
#define STACK_SIZE_TTY 0x8000
#define STACK_SIZE_TESTA 0x8000
#define STACK_SIZE_TESTB 0x8000
#define STACK_SIZE_TESTC 0x8000
#define STACK_SIZE_TOTAL (STACK_SIZE_TTY + \
STACK_SIZE_TESTA + \
STACK_SIZE_TESTB + \
STACK_SIZE_TESTC)
include/proto.h
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
proto.h
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Forrest Yu, 2005
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/* klib.asm */
PUBLIC void out_byte(u16 port, u8 value);
PUBLIC u8 in_byte(u16 port);
PUBLIC void disp_str(char * info);
PUBLIC void disp_color_str(char * info, int color);
/* protect.c */
PUBLIC void init_prot();
PUBLIC u32 seg2phys(u16 seg);
/* klib.c */
PUBLIC void delay(int time);
/* kernel.asm */
void restart();
/* main.c */
void TestA();
void TestB();
void TestC();
/* i8259.c */
PUBLIC void put_irq_handler(int irq, irq_handler handler);
PUBLIC void spurious_irq(int irq);
/* clock.c */
PUBLIC void clock_handler(int irq);
PUBLIC void init_clock();
/* keyboard.c */
PUBLIC void init_keyboard();
/* tty.c */
PUBLIC void task_tty();
PUBLIC void in_process(u32 key);
/* 以下是系統調用相關 */
/* proc.c */
PUBLIC int sys_get_ticks(); /* sys_call */
/* syscall.asm */
PUBLIC void sys_call(); /* int_handler */
PUBLIC int get_ticks();
kernel/clock.c
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
clock.c
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Forrest Yu, 2005
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
#include "type.h"
#include "const.h"
#include "protect.h"
#include "proto.h"
#include "string.h"
#include "proc.h"
#include "global.h"
/*======================================================================*
clock_handler
*======================================================================*/
PUBLIC void clock_handler(int irq)
{
ticks++;
p_proc_ready->ticks--;
if (k_reenter != 0) {
return;
}
if (p_proc_ready->ticks > 0) {
return;
}
schedule();
}
/*======================================================================*
milli_delay
*======================================================================*/
PUBLIC void milli_delay(int milli_sec)
{
int t = get_ticks();
while(((get_ticks() - t) * 1000 / HZ) < milli_sec) {}
}
/*======================================================================*
init_clock
*======================================================================*/
PUBLIC void init_clock()
{
/* 初始化 8253 PIT */
out_byte(TIMER_MODE, RATE_GENERATOR);
out_byte(TIMER0, (u8) (TIMER_FREQ/HZ) );
out_byte(TIMER0, (u8) ((TIMER_FREQ/HZ) >> 8));
put_irq_handler(CLOCK_IRQ, clock_handler); /* 设定时钟中断处理程序 */
enable_irq(CLOCK_IRQ); /* 让8259A可以接收时钟中断 */
}
kernel/global.c
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
global.c
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Forrest Yu, 2005
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
#define GLOBAL_VARIABLES_HERE
#include "type.h"
#include "const.h"
#include "protect.h"
#include "proto.h"
#include "proc.h"
#include "global.h"
PUBLIC PROCESS proc_table[NR_TASKS];
PUBLIC char task_stack[STACK_SIZE_TOTAL];
PUBLIC TASK task_table[NR_TASKS] = {{task_tty, STACK_SIZE_TTY, "tty"},
{TestA, STACK_SIZE_TESTA, "TestA"},
{TestB, STACK_SIZE_TESTB, "TestB"},
{TestC, STACK_SIZE_TESTC, "TestC"}};
PUBLIC irq_handler irq_table[NR_IRQ];
PUBLIC system_call sys_call_table[NR_SYS_CALL] = {sys_get_ticks};
kernel/keyboard.c
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
keyboard.c
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Forrest Yu, 2005
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
#include "type.h"
#include "const.h"
#include "protect.h"
#include "proto.h"
#include "string.h"
#include "proc.h"
#include "global.h"
#include "keyboard.h"
#include "keymap.h"
PRIVATE KB_INPUT kb_in;
PRIVATE int code_with_E0;
PRIVATE int shift_l; /* l shift state */
PRIVATE int shift_r; /* r shift state */
PRIVATE int alt_l; /* l alt state */
PRIVATE int alt_r; /* r left state */
PRIVATE int ctrl_l; /* l ctrl state */
PRIVATE int ctrl_r; /* l ctrl state */
PRIVATE int caps_lock; /* Caps Lock */
PRIVATE int num_lock; /* Num Lock */
PRIVATE int scroll_lock; /* Scroll Lock */
PRIVATE int column;
PRIVATE u8 get_byte_from_kbuf();
/*======================================================================*
keyboard_handler
*======================================================================*/
PUBLIC void keyboard_handler(int irq)
{
u8 scan_code = in_byte(KB_DATA);
if (kb_in.count < KB_IN_BYTES) {
*(kb_in.p_head) = scan_code;
kb_in.p_head++;
if (kb_in.p_head == kb_in.buf + KB_IN_BYTES) {
kb_in.p_head = kb_in.buf;
}
kb_in.count++;
}
}
/*======================================================================*
init_keyboard
*======================================================================*/
PUBLIC void init_keyboard()
{
kb_in.count = 0;
kb_in.p_head = kb_in.p_tail = kb_in.buf;
shift_l = shift_r = 0;
alt_l = alt_r = 0;
ctrl_l = ctrl_r = 0;
put_irq_handler(KEYBOARD_IRQ, keyboard_handler);/*設定鍵盤中斷處理程序*/
enable_irq(KEYBOARD_IRQ); /*開鍵盤中斷*/
}
/*======================================================================*
keyboard_read
*======================================================================*/
PUBLIC void keyboard_read()
{
u8 scan_code;
char output[2];
int make; /* 1: make; 0: break. */
u32 key = 0;/* 用一個整型來表示一個鍵。比如,如果 Home 被按下,
* 則 key 值將為定義在 keyboard.h 中的 'HOME'。
*/
u32* keyrow; /* 指向 keymap[] 的某一行 */
if(kb_in.count > 0){
code_with_E0 = 0;
scan_code = get_byte_from_kbuf();
/* 下面開始解析掃描碼 */
if (scan_code == 0xE1) {
int i;
u8 pausebrk_scode[] = {0xE1, 0x1D, 0x45,
0xE1, 0x9D, 0xC5};
int is_pausebreak = 1;
for(i=1;i<6;i++){
if (get_byte_from_kbuf() != pausebrk_scode[i]) {
is_pausebreak = 0;
break;
}
}
if (is_pausebreak) {
key = PAUSEBREAK;
}
}
else if (scan_code == 0xE0) {
scan_code = get_byte_from_kbuf();
/* PrintScreen 被按下 */
if (scan_code == 0x2A) {
if (get_byte_from_kbuf() == 0xE0) {
if (get_byte_from_kbuf() == 0x37) {
key = PRINTSCREEN;
make = 1;
}
}
}
/* PrintScreen 被釋放 */
if (scan_code == 0xB7) {
if (get_byte_from_kbuf() == 0xE0) {
if (get_byte_from_kbuf() == 0xAA) {
key = PRINTSCREEN;
make = 0;
}
}
}
/* 不是PrintScreen, 此時scan_code為0xE0緊跟的那個值. */
if (key == 0) {
code_with_E0 = 1;
}
}
if ((key != PAUSEBREAK) && (key != PRINTSCREEN)) {
/* 首先判斷Make Code 還是 Break Code */
make = (scan_code & FLAG_BREAK ? 0 : 1);
/* 先定位到 keymap 中的行 */
keyrow = &keymap[(scan_code & 0x7F) * MAP_COLS];
column = 0;
if (shift_l || shift_r) {
column = 1;
}
if (code_with_E0) {
column = 2;
code_with_E0 = 0;
}
key = keyrow[column];
switch(key) {
case SHIFT_L:
shift_l = make;
break;
case SHIFT_R:
shift_r = make;
break;
case CTRL_L:
ctrl_l = make;
break;
case CTRL_R:
ctrl_r = make;
break;
case ALT_L:
alt_l = make;
break;
case ALT_R:
alt_l = make;
break;
default:
break;
}
if (make) { /* 忽略 Break Code */
key |= shift_l ? FLAG_SHIFT_L : 0;
key |= shift_r ? FLAG_SHIFT_R : 0;
key |= ctrl_l ? FLAG_CTRL_L : 0;
key |= ctrl_r ? FLAG_CTRL_R : 0;
key |= alt_l ? FLAG_ALT_L : 0;
key |= alt_r ? FLAG_ALT_R : 0;
in_process(key);
}
}
}
}
/*======================================================================*
get_byte_from_kbuf
*======================================================================*/
PRIVATE u8 get_byte_from_kbuf() /* 從鍵盤緩衝區中讀取下一個字節 */
{
u8 scan_code;
while (kb_in.count <= 0) {} /* 等待下一個字節到來 */
disable_int();
scan_code = *(kb_in.p_tail);
kb_in.p_tail++;
if (kb_in.p_tail == kb_in.buf + KB_IN_BYTES) {
kb_in.p_tail = kb_in.buf;
}
kb_in.count--;
enable_int();
return scan_code;
}
kernel/main.c
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
main.c
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Forrest Yu, 2005
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
#include "type.h"
#include "const.h"
#include "protect.h"
#include "proto.h"
#include "string.h"
#include "proc.h"
#include "global.h"
/*======================================================================*
kernel_main
*======================================================================*/
PUBLIC int kernel_main()
{
disp_str("-----\"kernel_main\" begins-----\n");
TASK* p_task = task_table;
PROCESS* p_proc = proc_table;
char* p_task_stack = task_stack + STACK_SIZE_TOTAL;
u16 selector_ldt = SELECTOR_LDT_FIRST;
int i;
for (i = 0; i < NR_TASKS; i++) {
strcpy(p_proc->p_name, p_task->name); // name of the process
p_proc->pid = i; // pid
p_proc->ldt_sel = selector_ldt;
memcpy(&p_proc->ldts[0], &gdt[SELECTOR_KERNEL_CS >> 3],
sizeof(DESCRIPTOR));
p_proc->ldts[0].attr1 = DA_C | PRIVILEGE_TASK << 5;
memcpy(&p_proc->ldts[1], &gdt[SELECTOR_KERNEL_DS >> 3],
sizeof(DESCRIPTOR));
p_proc->ldts[1].attr1 = DA_DRW | PRIVILEGE_TASK << 5;
p_proc->regs.cs = ((8 * 0) & SA_RPL_MASK & SA_TI_MASK)
| SA_TIL | RPL_TASK;
p_proc->regs.ds = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK)
| SA_TIL | RPL_TASK;
p_proc->regs.es = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK)
| SA_TIL | RPL_TASK;
p_proc->regs.fs = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK)
| SA_TIL | RPL_TASK;
p_proc->regs.ss = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK)
| SA_TIL | RPL_TASK;
p_proc->regs.gs = (SELECTOR_KERNEL_GS & SA_RPL_MASK)
| RPL_TASK;
p_proc->regs.eip = (u32)p_task->initial_eip;
p_proc->regs.esp = (u32)p_task_stack;
p_proc->regs.eflags = 0x1202; /* IF=1, IOPL=1 */
p_task_stack -= p_task->stacksize;
p_proc++;
p_task++;
selector_ldt += 1 << 3;
}
proc_table[0].ticks = proc_table[0].priority = 15;
proc_table[1].ticks = proc_table[1].priority = 5;
proc_table[2].ticks = proc_table[2].priority = 3;
k_reenter = 0;
ticks = 0;
p_proc_ready = proc_table;
init_clock();
init_keyboard();
restart();
while(1){}
}
/*======================================================================*
TestA
*======================================================================*/
void TestA()
{
int i = 0;
while (1) {
/* disp_str("A."); */
milli_delay(10);
}
}
/*======================================================================*
TestB
*======================================================================*/
void TestB()
{
int i = 0x1000;
while(1){
/* disp_str("B."); */
milli_delay(10);
}
}
/*======================================================================*
TestB
*======================================================================*/
void TestC()
{
int i = 0x2000;
while(1){
/* disp_str("C."); */
milli_delay(10);
}
}
kernel/tty.c
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
tty.c
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Forrest Yu, 2005
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
#include "type.h"
#include "const.h"
#include "protect.h"
#include "proto.h"
#include "string.h"
#include "proc.h"
#include "global.h"
#include "keyboard.h"
/*======================================================================*
task_tty
*======================================================================*/
PUBLIC void task_tty()
{
while (1) {
keyboard_read();
}
}
/*======================================================================*
in_process
*======================================================================*/
PUBLIC void in_process(u32 key)
{
char output[2] = {'\0', '\0'};
if (!(key & FLAG_EXT)) {
output[0] = key & 0xFF;
disp_str(output);
}
}
lib/kliba.asm
; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; klib.asm
; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; Forrest Yu, 2005
; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
%include "sconst.inc"
; 導入全局變量
extern disp_pos
[SECTION .text]
; 導出函數
global disp_str
global disp_color_str
global out_byte
global in_byte
global enable_irq
global disable_irq
global enable_int
global disable_int
; ========================================================================
; void disp_str(char * info);
; ========================================================================
disp_str:
push ebp
mov ebp, esp
mov esi, [ebp + 8] ; pszInfo
mov edi, [disp_pos]
mov ah, 0Fh
.1:
lodsb
test al, al
jz .2
cmp al, 0Ah ; 是ENTER嗎?
jnz .3
push eax
mov eax, edi
mov bl, 160
div bl
and eax, 0FFh
inc eax
mov bl, 160
mul bl
mov edi, eax
pop eax
jmp .1
.3:
mov [gs:edi], ax
add edi, 2
jmp .1
.2:
mov [disp_pos], edi
pop ebp
ret
; ========================================================================
; void disp_color_str(char * info, int color);
; ========================================================================
disp_color_str:
push ebp
mov ebp, esp
mov esi, [ebp + 8] ; pszInfo
mov edi, [disp_pos]
mov ah, [ebp + 12] ; color
.1:
lodsb
test al, al
jz .2
cmp al, 0Ah ; 是ENTER嗎?
jnz .3
push eax
mov eax, edi
mov bl, 160
div bl
and eax, 0FFh
inc eax
mov bl, 160
mul bl
mov edi, eax
pop eax
jmp .1
.3:
mov [gs:edi], ax
add edi, 2
jmp .1
.2:
mov [disp_pos], edi
pop ebp
ret
; ========================================================================
; void out_byte(u16 port, u8 value);
; ========================================================================
out_byte:
mov edx, [esp + 4] ; port
mov al, [esp + 4 + 4] ; value
out dx, al
nop ; 一點延遲
nop
ret
; ========================================================================
; u8 in_byte(u16 port);
; ========================================================================
in_byte:
mov edx, [esp + 4] ; port
xor eax, eax
in al, dx
nop ; 一點延遲
nop
ret
; ========================================================================
; void disable_irq(int irq);
; ========================================================================
; Disable an interrupt request line by setting an 8259 bit.
; Equivalent code:
; if(irq < 8){
; out_byte(INT_M_CTLMASK, in_byte(INT_M_CTLMASK) | (1 << irq));
; }
; else{
; out_byte(INT_S_CTLMASK, in_byte(INT_S_CTLMASK) | (1 << irq));
; }
disable_irq:
mov ecx, [esp + 4] ; irq
pushf
cli
mov ah, 1
rol ah, cl ; ah = (1 << (irq % 8))
cmp cl, 8
jae disable_8 ; disable irq >= 8 at the slave 8259
disable_0:
in al, INT_M_CTLMASK
test al, ah
jnz dis_already ; already disabled?
or al, ah
out INT_M_CTLMASK, al ; set bit at master 8259
popf
mov eax, 1 ; disabled by this function
ret
disable_8:
in al, INT_S_CTLMASK
test al, ah
jnz dis_already ; already disabled?
or al, ah
out INT_S_CTLMASK, al ; set bit at slave 8259
popf
mov eax, 1 ; disabled by this function
ret
dis_already:
popf
xor eax, eax ; already disabled
ret
; ========================================================================
; void enable_irq(int irq);
; ========================================================================
; Enable an interrupt request line by clearing an 8259 bit.
; Equivalent code:
; if(irq < 8){
; out_byte(INT_M_CTLMASK, in_byte(INT_M_CTLMASK) & ~(1 << irq));
; }
; else{
; out_byte(INT_S_CTLMASK, in_byte(INT_S_CTLMASK) & ~(1 << irq));
; }
;
enable_irq:
mov ecx, [esp + 4] ; irq
pushf
cli
mov ah, ~1
rol ah, cl ; ah = ~(1 << (irq % 8))
cmp cl, 8
jae enable_8 ; enable irq >= 8 at the slave 8259
enable_0:
in al, INT_M_CTLMASK
and al, ah
out INT_M_CTLMASK, al ; clear bit at master 8259
popf
ret
enable_8:
in al, INT_S_CTLMASK
and al, ah
out INT_S_CTLMASK, al ; clear bit at slave 8259
popf
ret
; ========================================================================
; void disable_int();
; ========================================================================
disable_int:
cli
ret
; ========================================================================
; void enable_int();
; ========================================================================
enable_int:
sti
ret
lib/klib.c
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
klib.c
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Forrest Yu, 2005
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
#include "type.h"
#include "const.h"
#include "protect.h"
#include "proto.h"
#include "string.h"
#include "proc.h"
#include "global.h"
/*======================================================================*
itoa
*======================================================================*/
PUBLIC char * itoa(char * str, int num)/* 數字前面的 0 不被顯示出來, 比如 0000B800 被顯示成 B800 */
{
char * p = str;
char ch;
int i;
int flag = 0;
*p++ = '0';
*p++ = 'x';
if(num == 0){
*p++ = '0';
}
else{
for(i=28;i>=0;i-=4){
ch = (num >> i) & 0xF;
if(flag || (ch > 0)){
flag = 1;
ch += '0';
if(ch > '9'){
ch += 7;
}
*p++ = ch;
}
}
}
*p = 0;
return str;
}
/*======================================================================*
disp_int
*======================================================================*/
PUBLIC void disp_int(int input)
{
char output[16];
itoa(output, input);
disp_str(output);
}
/*======================================================================*
delay
*======================================================================*/
PUBLIC void delay(int time)
{
int i, j, k;
for(k=0;k<time;k++){
/*for(i=0;i<10000;i++){ for Virtual PC */
for(i=0;i<10;i++){/* for Bochs */
for(j=0;j<10000;j++){}
}
}
}
Makefile
######################### # Makefile for Orange'S # ######################### # Entry point of Orange'S # It must have the same value with 'KernelEntryPointPhyAddr' in load.inc! ENTRYPOINT = 0x30400 # Offset of entry point in kernel file # It depends on ENTRYPOINT ENTRYOFFSET = 0x400 # Programs, flags, etc. ASM = nasm DASM = ndisasm CC = gcc LD = ld ASMBFLAGS = -I boot/include/ ASMKFLAGS = -I include/ -f elf CFLAGS = -I include/ -m32 -c -fno-builtin -fno-stack-protector LDFLAGS = -s -melf_i386 -Ttext $(ENTRYPOINT) DASMFLAGS = -u -o $(ENTRYPOINT) -e $(ENTRYOFFSET) # This Program ORANGESBOOT = boot/boot.bin boot/loader.bin ORANGESKERNEL = kernel.bin OBJS = kernel/kernel.o kernel/syscall.o kernel/start.o kernel/main.o kernel/clock.o\ kernel/i8259.o kernel/global.o kernel/protect.o kernel/proc.o\ lib/kliba.o lib/klib.o lib/string.o DASMOUTPUT = kernel.bin.asm # All Phony Targets .PHONY : everything final image clean realclean disasm all buildimg # Default starting position nop : @echo "why not \`make image' huh? :)" everything : $(ORANGESBOOT) $(ORANGESKERNEL) all : realclean everything image : realclean everything clean buildimg clean : rm -f $(OBJS) realclean : rm -f $(OBJS) $(ORANGESBOOT) $(ORANGESKERNEL) disasm : $(DASM) $(DASMFLAGS) $(ORANGESKERNEL) > $(DASMOUTPUT) # We assume that "a.img" exists in current folder buildimg : mkdir tmp sleep 1 sudo mount -o loop a.img tmp sleep 1 sudo cp -fv boot/loader.bin tmp sudo cp -fv kernel.bin tmp sleep 1 sudo umount tmp sleep 1 rmdir tmp boot/boot.bin : boot/boot.asm boot/include/load.inc boot/include/fat12hdr.inc $(ASM) $(ASMBFLAGS) -o $@ $< boot/loader.bin : boot/loader.asm boot/include/load.inc boot/include/fat12hdr.inc boot/include/pm.inc $(ASM) $(ASMBFLAGS) -o $@ $< $(ORANGESKERNEL) : $(OBJS) $(LD) $(LDFLAGS) -o $(ORANGESKERNEL) $(OBJS) kernel/kernel.o : kernel/kernel.asm include/sconst.inc $(ASM) $(ASMKFLAGS) -o $@ $< kernel/syscall.o : kernel/syscall.asm include/sconst.inc $(ASM) $(ASMKFLAGS) -o $@ $< kernel/start.o: kernel/start.c include/type.h include/const.h include/protect.h include/string.h include/proc.h include/proto.h \ include/global.h $(CC) $(CFLAGS) -o $@ $< kernel/main.o: kernel/main.c include/type.h include/const.h include/protect.h include/string.h include/proc.h include/proto.h \ include/global.h $(CC) $(CFLAGS) -o $@ $< kernel/clock.o: kernel/clock.c $(CC) $(CFLAGS) -o $@ $< kernel/i8259.o: kernel/i8259.c include/type.h include/const.h include/protect.h include/proto.h $(CC) $(CFLAGS) -o $@ $< kernel/global.o: kernel/global.c include/type.h include/const.h include/protect.h include/proc.h \ include/global.h include/proto.h $(CC) $(CFLAGS) -o $@ $< kernel/protect.o: kernel/protect.c include/type.h include/const.h include/protect.h include/proc.h include/proto.h \ include/global.h $(CC) $(CFLAGS) -o $@ $< kernel/proc.o: kernel/proc.c $(CC) $(CFLAGS) -o $@ $< lib/klib.o: lib/klib.c include/type.h include/const.h include/protect.h include/string.h include/proc.h include/proto.h \ include/global.h $(CC) $(CFLAGS) -o $@ $< lib/kliba.o : lib/kliba.asm $(ASM) $(ASMKFLAGS) -o $@ $< lib/string.o : lib/string.asm $(ASM) $(ASMKFLAGS) -o $@ $<
![]() |
| 執行結果 |
目錄結構
.
├── a.img
├── boot
│ ├── boot.asm
│ ├── include
│ │ ├── fat12hdr.inc
│ │ ├── load.inc
│ │ └── pm.inc
│ └── loader.asm
├── include
│ ├── const.h
│ ├── global.h
│ ├── keyboard.h
│ ├── keymap.h
│ ├── proc.h
│ ├── protect.h
│ ├── proto.h
│ ├── sconst.inc
│ ├── string.h
│ └── type.h
├── kernel
│ ├── clock.c
│ ├── global.c
│ ├── i8259.c
│ ├── kernel.asm
│ ├── keyboard.c
│ ├── main.c
│ ├── proc.c
│ ├── protect.c
│ ├── start.c
│ ├── syscall.asm
│ └── tty.c
└── lib
├── kliba.asm
├── klib.c
└── string.asm
.png)
留言
張貼留言