敲擊鍵盤有兩個方面的含義:動作和內容。
.
├── 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
留言
張貼留言