赞
踩
内核级命令如何实现?
通过系统调用
命令所对应的功能需要内核协助才能实现
1. 在系统启动时,在实模式下获取物理内存容量 (int 0x15)
2. 将物理内存容量暂存于共享内存区
3. 内核执行时,从共享内存区获取物理内存容量 (存入全局变量)
4. 实现系统调用 uint GetMemSize()
5. Shell 任务通过 uint GetMemSize() 实现命令 mem 并打印容量大小
common.asm
- BaseOfSharedMemory equ 0xA000
-
- ; Shared Value Address
-
- GdtEntry equ BaseOfSharedMemory + 0
- GdtSize equ BaseOfSharedMemory + 4
- IdtEntry equ BaseOfSharedMemory + 8
- IdtSize equ BaseOfSharedMemory + 12
- RunTaskEntry equ BaseOfSharedMemory + 16
- InitInterruptEntry equ BaseOfSharedMemory + 20
- MemSize equ BaseOfSharedMemory + 24
- SendEOIEntry equ BaseOfSharedMemory + 28
- LoadTaskEntry equ BaseOfSharedMemory + 32
- AppMainEntry equ BaseOfSharedMemory + 36
loader.asm
- ;
- ;
- GetMemSize:
- mov dword [MemSize], 0
- xor eax, eax
- mov ax, 0xE801
-
- int 0x15
-
- jc geterr
-
- shl eax, 10 ; eax = eax * 1024
- shl ebx, 6 + 10 ; ebx = ebx * 64 * 1024
-
- mov ecx, 1
- shl ecx, 20 ; ecx = 1024 * 1024
-
- add dword[MemSize], eax
- add dword[MemSize], ebx
- add dword[MemSize], ecx
-
- jmp getok
-
- geterr:
- mov dword [MemSize], 0
-
- getok:
- ret
kentry.asm
- ;
- ;
- InitGlobal:
- push ebp
- mov ebp, esp
-
- mov eax, dword [GdtEntry]
- mov [gGdtInfo], eax
- mov eax, dword [GdtSize]
- mov [gGdtInfo + 4], eax
-
- mov eax, dword [IdtEntry]
- mov [gIdtInfo], eax
- mov eax, dword [IdtSize]
- mov [gIdtInfo + 4], eax
-
- mov eax, dword [RunTaskEntry]
- mov dword [RunTask], eax
-
- mov eax, dword [InitInterruptEntry]
- mov dword [InitInterrupt], eax
-
- mov eax, dword [SendEOIEntry]
- mov dword [SendEOI], eax
-
- mov eax, dword [LoadTaskEntry]
- mov dword [LoadTask], eax
-
- mov eax, dword [MemSize]
- mov dword [gMemSize], eax
-
- leave
-
- ret
syscall.c
- uint GetMemSize()
- {
- uint ret = 0;
-
- SysCall(3, 0, &ret, 0);
-
- return ret;
- }
ihandler.c
- void SysCallHandler(uint type, uint cmd, uint param1, uint param2) // __cdcel__
- {
- switch(type)
- {
- case 0:
- TaskCallHandler(cmd, param1, param2);
- break;
- case 1:
- MutexCallHandler(cmd, param1, param2);
- break;
- case 2:
- KeyCallHandler(cmd, param1, param2);
- case 3:
- SysInfoHandler(cmd, param1, param2);
- break;
- default:
- break;
- }
- }
sysinfo.c
- uint gMemSize = 0;
-
- void SysInfoHandler(uint cmd, uint param1, uint param2)
- {
- if(cmd == 0)
- {
- uint* pRet = (uint*)param1;
-
- *pRet = gMemSize;
- }
- }
shell.c
- static void Mem()
- {
- uint ms = GetMemSize() >> 20;
-
- ClearCmdInfo();
-
- SetPrintPos(CMD_START_W, CMD_START_H + 1);
- PrintString("Physical Memory: ");
- PrintIntDec(ms);
- PrintString(" MB\n");
- }
-
- void Shell()
- {
- List_Init(&gCmdList);
-
- AddCmdEntry("clear", Clear);
- AddCmdEntry("demo1", Demo1);
- AddCmdEntry("demo2", Demo2);
- AddCmdEntry("mem", Mem);
-
- SetPrintPos(CMD_START_W, CMD_START_H);
-
- PrintString(PROMPT);
-
- while(1)
- {
- uint key = ReadKey();
-
- if(IsKeyDown(key))
- {
- char ch = GetChar(key);
- byte vc = GetKeyCode(key);
-
- Handler(ch, vc);
- }
- }
- }
GetMemSize 函数中获取到的内存容量的单位为 Byte,我们把它显示为 MB,所以需要将获取到的内存大小右移20位。
执行 mem 命令结果如下图所示
该系统中物理内存大小为 128MB
Shell 的本质是一个任务 (执行于用户态)
Shell 是命令解释器,解释用户输入的命令
Shell 命令可分为3种类型:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。