/** * 현재 생성된 모든 태스크의 정보를 출력 */ static void kShowTaskList( const char* pcParameterBuffer ) { int i; TCB* pstTCB; int iCount = 0; kPrintf( "=========== Task Total Count [%d] ===========\n", kGetTaskCount() ); for( i = 0 ; i < TASK_MAXCOUNT ; i++ ) { // TCB를 구해서 TCB가 사용 중이면 ID를 출력 pstTCB = kGetTCBInTCBPool( i ); if( ( pstTCB->stLink.qwID >> 32 ) != 0 ) { // 태스크가 10개 출력될 때마다, 계속 태스크 정보를 표시할지 여부를 확인 if( ( iCount != 0 ) && ( ( iCount % 10 ) == 0 ) ) { kPrintf( "Press any key to continue... ('q' is exit) : " ); if( kGetCh() == 'q' ) { kPrintf( "\n" ); break; } kPrintf( "\n" ); } kPrintf( "[%d] Task ID[0x%Q], Priority[%d], Flags[0x%Q], Thread[%d]\n", 1 + iCount++, pstTCB->stLink.qwID, GETPRIORITY( pstTCB->qwFlags ), pstTCB->qwFlags, kGetListCount( &( pstTCB->stChildThreadList ) ) ); kPrintf( " Parent PID[0x%Q], Memory Address[0x%Q], Size[0x%Q]\n", pstTCB->qwParentProcessID, pstTCB->pvMemoryAddress, pstTCB->qwMemorySize ); } } }
/** * PC를 재시작(Reboot) */ void kShutdown( const char* pcParamegerBuffer ) { kPrintf( "System Shutdown Start...\n" ); // 키보드 컨트롤러를 통해 PC를 재시작 kPrintf( "Press Any Key To Reboot PC..." ); kGetCh(); kReboot(); }
// Restart PC void kShutdown( const char* pcParameterBuffer ) { kPrintf( "System Shutdown Start..\n" ); // PC restart by keyboard controller kPrintf( "Press Any Key To Reboot PC..." ); kGetCh(); kReboot(); }
// Test for context switching void kTestTask(void) { int i = 0; while (1) { // Print message and wait for key input kPrintf("[%d] This message is from kTestTask. Press any key to switch " "kConsolShell!!\n", i++); kGetCh(); // Context switching kSwitchContext(&(gs_vstTask[1].stContext), &(gs_vstTask[0].stContext)); } }
/** * 태스크 전환을 테스트하는 태스크 */ void kTestTask( void ) { int i = 0; while( 1 ) { // 메시지를 출력하고 키 입력을 대기 kPrintf( "[%d] This message is from kTestTask. Press any key to switch " "kConsoleShell~!!\n", i++ ); kGetCh(); // 위에서 키가 입력되면 태스크를 전환 kSwitchContext( &( gs_vstTask[ 1 ].stContext ), &( gs_vstTask[ 0 ].stContext ) ); } }
/** * 셸 도움말을 출력 */ static void kHelp( const char* pcCommandBuffer ) { int i; int iCount; int iCursorX, iCursorY; int iLength, iMaxCommandLength = 0; kPrintf( "=========================================================\n" ); kPrintf( " MINT64 Shell Help \n" ); kPrintf( "=========================================================\n" ); iCount = sizeof( gs_vstCommandTable ) / sizeof( SHELLCOMMANDENTRY ); // 가장 긴 커맨드의 길이를 계산 for( i = 0 ; i < iCount ; i++ ) { iLength = kStrLen( gs_vstCommandTable[ i ].pcCommand ); if( iLength > iMaxCommandLength ) { iMaxCommandLength = iLength; } } // 도움말 출력 for( i = 0 ; i < iCount ; i++ ) { kPrintf( "%s", gs_vstCommandTable[ i ].pcCommand ); kGetCursor( &iCursorX, &iCursorY ); kSetCursor( iMaxCommandLength, iCursorY ); kPrintf( " - %s\n", gs_vstCommandTable[ i ].pcHelp ); // 목록이 많을 경우 나눠서 보여줌 if( ( i != 0 ) && ( ( i % 20 ) == 0 ) ) { kPrintf( "Press any key to continue... ('q' is exit) : " ); if( kGetCh() == 'q' ) { kPrintf( "\n" ); break; } kPrintf( "\n" ); } } }
/** * PC를 재시작(Reboot) */ static void kShutdown( const char* pcParamegerBuffer ) { kPrintf( "System Shutdown Start...\n" ); // 파일 시스템 캐시에 들어있는 내용을 하드 디스크로 옮김 kPrintf( "Cache Flush... "); if( kFlushFileSystemCache() == TRUE ) { kPrintf( "Pass\n" ); } else { kPrintf( "Fail\n" ); } // 키보드 컨트롤러를 통해 PC를 재시작 kPrintf( "Press Any Key To Reboot PC..." ); kGetCh(); kReboot(); }
/** * 태스크를 생성해서 멀티 태스킹 수행 */ void kCreateTestTask( const char* pcParameterBuffer ) { KEYDATA stData; int i = 0; // 태스크 설정 kSetUpTask( &( gs_vstTask[ 1 ] ), 1, 0, ( QWORD ) kTestTask, &( gs_vstStack ), sizeof( gs_vstStack ) ); // 'q' 키가 입력되지 않을 때까지 수행 while( 1 ) { // 메시지를 출력하고 키 입력을 대기 kPrintf( "[%d] This message is from kConsoleShell. Press any key to " "switch TestTask~!!\n", i++ ); if( kGetCh() == 'q' ) { break; } // 위에서 키가 입력되면 태스크를 전환 kSwitchContext( &( gs_vstTask[ 0 ].stContext ), &( gs_vstTask[ 1 ].stContext ) ); } }
/** * 셸의 메인 루프 */ void kStartConsoleShell( void ) { char vcCommandBuffer[ CONSOLESHELL_MAXCOMMANDBUFFERCOUNT ]; int iCommandBufferIndex = 0; BYTE bKey; int iCursorX, iCursorY; CONSOLEMANAGER* pstConsoleManager; // 콘솔을 관리하는 자료구조를 반환 pstConsoleManager = kGetConsoleManager(); // 프롬프트 출력 kPrintf( CONSOLESHELL_PROMPTMESSAGE ); // 콘솔 셸 종료 플래그가 TRUE가 될 때까지 반복 while( pstConsoleManager->bExit == FALSE ) { bKey = kGetCh(); // 콘솔 셸 종료 플래그가 설정된 경우 루프를 종료 if( pstConsoleManager->bExit == TRUE ) { break; } if( bKey == KEY_BACKSPACE ) { if( iCommandBufferIndex > 0 ) { // 현재 커서 위치를 얻어서 한 문자 앞으로 이동한 다음 공백을 출력하고 // 커맨드 버퍼에서 마지막 문자 삭제 kGetCursor( &iCursorX, &iCursorY ); kPrintStringXY( iCursorX - 1, iCursorY, " " ); kSetCursor( iCursorX - 1, iCursorY ); iCommandBufferIndex--; } } else if( bKey == KEY_ENTER ) { kPrintf( "\n" ); if( iCommandBufferIndex > 0 ) { // 커맨드 버퍼에 있는 명령을 실행 vcCommandBuffer[ iCommandBufferIndex ] = '\0'; kExecuteCommand( vcCommandBuffer ); } // 프롬프트 출력 및 커맨드 버퍼 초기화 kPrintf( "%s", CONSOLESHELL_PROMPTMESSAGE ); kMemSet( vcCommandBuffer, '\0', CONSOLESHELL_MAXCOMMANDBUFFERCOUNT ); iCommandBufferIndex = 0; } // 시프트 키, CAPS Lock, NUM Lock, Scroll Lock은 무시 else if( ( bKey == KEY_LSHIFT ) || ( bKey == KEY_RSHIFT ) || ( bKey == KEY_CAPSLOCK ) || ( bKey == KEY_NUMLOCK ) || ( bKey == KEY_SCROLLLOCK ) ) { ; } else if( bKey < 128 ) { // TAB은 공백으로 전환 if( bKey == KEY_TAB ) { bKey = ' '; } // 버퍼가 남아있을 때만 가능 if( iCommandBufferIndex < CONSOLESHELL_MAXCOMMANDBUFFERCOUNT ) { vcCommandBuffer[ iCommandBufferIndex++ ] = bKey; kPrintf( "%c", bKey ); } } } }
/** * 현재 생성된 모든 태스크의 정보를 출력 */ static void kShowTaskList( const char* pcParameterBuffer ) { int i; TCB* pstTCB; int iCount = 0; int iTotalTaskCount = 0; char vcBuffer[ 20 ]; int iRemainLength; int iProcessorCount; // 코어 수만큼 루프를 돌면서 각 스케줄러에 있는 태스크의 수를 더함 iProcessorCount = kGetProcessorCount(); for( i = 0 ; i < iProcessorCount ; i++ ) { iTotalTaskCount += kGetTaskCount( i ); } kPrintf( "================= Task Total Count [%d] =================\n", iTotalTaskCount ); // 코어가 2개 이상이면 각 스케줄러 별로 개수를 출력 if( iProcessorCount > 1 ) { // 각 스케줄러 별로 태스크의 개수를 출력 for( i = 0 ; i < iProcessorCount ; i++ ) { if( ( i != 0 ) && ( ( i % 4 ) == 0 ) ) { kPrintf( "\n" ); } kSPrintf( vcBuffer, "Core %d : %d", i, kGetTaskCount( i ) ); kPrintf( vcBuffer ); // 출력하고 남은 공간을 모두 스페이스바로 채움 iRemainLength = 19 - kStrLen( vcBuffer ); kMemSet( vcBuffer, ' ', iRemainLength ); vcBuffer[ iRemainLength ] = '\0'; kPrintf( vcBuffer ); } kPrintf( "\nPress any key to continue... ('q' is exit) : " ); if( kGetCh() == 'q' ) { kPrintf( "\n" ); return ; } kPrintf( "\n\n" ); } for( i = 0 ; i < TASK_MAXCOUNT ; i++ ) { // TCB를 구해서 TCB가 사용 중이면 ID를 출력 pstTCB = kGetTCBInTCBPool( i ); if( ( pstTCB->stLink.qwID >> 32 ) != 0 ) { // 태스크가 6개 출력될 때마다, 계속 태스크 정보를 표시할지 여부를 확인 if( ( iCount != 0 ) && ( ( iCount % 6 ) == 0 ) ) { kPrintf( "Press any key to continue... ('q' is exit) : " ); if( kGetCh() == 'q' ) { kPrintf( "\n" ); break; } kPrintf( "\n" ); } kPrintf( "[%d] Task ID[0x%Q], Priority[%d], Flags[0x%Q], Thread[%d]\n", 1 + iCount++, pstTCB->stLink.qwID, GETPRIORITY( pstTCB->qwFlags ), pstTCB->qwFlags, kGetListCount( &( pstTCB->stChildThreadList ) ) ); kPrintf( " Core ID[0x%X] CPU Affinity[0x%X]\n", pstTCB->bAPICID, pstTCB->bAffinity ); kPrintf( " Parent PID[0x%Q], Memory Address[0x%Q], Size[0x%Q]\n", pstTCB->qwParentProcessID, pstTCB->pvMemoryAddress, pstTCB->qwMemorySize ); } } }
/** * 셸의 메인 루프 */ void kStartConsoleShell( void ) { char vcCommandBuffer[ CONSOLESHELL_MAXCOMMANDBUFFERCOUNT ]; int iCommandBufferIndex = 0; BYTE bKey; int iCursorX, iCursorY; // 프롬프트 출력 kPrintf( CONSOLESHELL_PROMPTMESSAGE ); while( 1 ) { // 키가 수신될 때까지 대기 bKey = kGetCh(); // Backspace 키 처리 if( bKey == KEY_BACKSPACE ) { if( iCommandBufferIndex > 0 ) { // 현재 커서 위치를 얻어서 한 문자 앞으로 이동한 다음 공백을 출력하고 // 커맨드 버퍼에서 마지막 문자 삭제 kGetCursor( &iCursorX, &iCursorY ); kPrintStringXY( iCursorX - 1, iCursorY, " " ); kSetCursor( iCursorX - 1, iCursorY ); iCommandBufferIndex--; } } // 엔터 키 처리 else if( bKey == KEY_ENTER ) { kPrintf( "\n" ); if( iCommandBufferIndex > 0 ) { // 커맨드 버퍼에 있는 명령을 실행 vcCommandBuffer[ iCommandBufferIndex ] = '\0'; kExecuteCommand( vcCommandBuffer ); } // 프롬프트 출력 및 커맨드 버퍼 초기화 kPrintf( "%s", CONSOLESHELL_PROMPTMESSAGE ); kMemSet( vcCommandBuffer, '\0', CONSOLESHELL_MAXCOMMANDBUFFERCOUNT ); iCommandBufferIndex = 0; } // 시프트 키, CAPS Lock, NUM Lock, Scroll Lock은 무시 else if( ( bKey == KEY_LSHIFT ) || ( bKey == KEY_RSHIFT ) || ( bKey == KEY_CAPSLOCK ) || ( bKey == KEY_NUMLOCK ) || ( bKey == KEY_SCROLLLOCK ) ) { ; } else { // TAB은 공백으로 전환 if( bKey == KEY_TAB ) { bKey = ' '; } // 버퍼에 공간이 남아있을 때만 가능 if( iCommandBufferIndex < CONSOLESHELL_MAXCOMMANDBUFFERCOUNT ) { vcCommandBuffer[ iCommandBufferIndex++ ] = bKey; kPrintf( "%c", bKey ); } } } }
/** * MP 설정 테이블의 정보를 모두 화면에 출력 */ void kPrintMPConfigurationTable( void ) { MPCONFIGRUATIONMANAGER* pstMPConfigurationManager; QWORD qwMPFloatingPointerAddress; MPFLOATINGPOINTER* pstMPFloatingPointer; MPCONFIGURATIONTABLEHEADER* pstMPTableHeader; PROCESSORENTRY* pstProcessorEntry; BUSENTRY* pstBusEntry; IOAPICENTRY* pstIOAPICEntry; IOINTERRUPTASSIGNMENTENTRY* pstIOAssignmentEntry; LOCALINTERRUPTASSIGNMENTENTRY* pstLocalAssignmentEntry; QWORD qwBaseEntryAddress; char vcStringBuffer[ 20 ]; WORD i; BYTE bEntryType; // 화면에 출력할 문자열 char* vpcInterruptType[ 4 ] = { "INT", "NMI", "SMI", "ExtINT" }; char* vpcInterruptFlagsPO[ 4 ] = { "Conform", "Active High", "Reserved", "Active Low" }; char* vpcInterruptFlagsEL[ 4 ] = { "Conform", "Edge-Trigger", "Reserved", "Level-Trigger"}; //========================================================================== // MP 설정 테이블 처리 함수를 먼저 호출하여 시스템 처리에 필요한 정보를 저장 //========================================================================== kPrintf( "================ MP Configuration Table Summary ================\n" ); pstMPConfigurationManager = kGetMPConfigurationManager(); if( ( pstMPConfigurationManager->qwBaseEntryStartAddress == 0 ) && ( kAnalysisMPConfigurationTable() == FALSE ) ) { kPrintf( "MP Configuration Table Analysis Fail\n" ); return ; } kPrintf( "MP Configuration Table Analysis Success\n" ); kPrintf( "MP Floating Pointer Address : 0x%Q\n", pstMPConfigurationManager->pstMPFloatingPointer ); kPrintf( "PIC Mode Support : %d\n", pstMPConfigurationManager->bUsePICMode ); kPrintf( "MP Configuration Table Header Address : 0x%Q\n", pstMPConfigurationManager->pstMPConfigurationTableHeader ); kPrintf( "Base MP Configuration Table Entry Start Address : 0x%Q\n", pstMPConfigurationManager->qwBaseEntryStartAddress ); kPrintf( "Processor Count : %d\n", pstMPConfigurationManager->iProcessorCount ); kPrintf( "ISA Bus ID : %d\n", pstMPConfigurationManager->bISABusID ); kPrintf( "Press any key to continue... ('q' is exit) : " ); if( kGetCh() == 'q' ) { kPrintf( "\n" ); return ; } kPrintf( "\n" ); //========================================================================== // MP 플로팅 포인터 정보를 출력 //========================================================================== kPrintf( "=================== MP Floating Pointer ===================\n" ); pstMPFloatingPointer = pstMPConfigurationManager->pstMPFloatingPointer; kMemCpy( vcStringBuffer, pstMPFloatingPointer->vcSignature, 4 ); vcStringBuffer[ 4 ] = '\0'; kPrintf( "Signature : %s\n", vcStringBuffer ); kPrintf( "MP Configuration Table Address : 0x%Q\n", pstMPFloatingPointer->dwMPConfigurationTableAddress ); kPrintf( "Length : %d * 16 Byte\n", pstMPFloatingPointer->bLength ); kPrintf( "Version : %d\n", pstMPFloatingPointer->bRevision ); kPrintf( "CheckSum : 0x%X\n", pstMPFloatingPointer->bCheckSum ); kPrintf( "Feature Byte 1 : 0x%X ", pstMPFloatingPointer->vbMPFeatureByte[ 0 ] ); // MP 설정 테이블 사용 여부 출력 if( pstMPFloatingPointer->vbMPFeatureByte[ 0 ] == 0 ) { kPrintf( "(Use MP Configuration Table)\n" ); } else { kPrintf( "(Use Default Configuration)\n" ); } // PIC 모드 지원 여부 출력 kPrintf( "Feature Byte 2 : 0x%X ", pstMPFloatingPointer->vbMPFeatureByte[ 1 ] ); if( pstMPFloatingPointer->vbMPFeatureByte[ 2 ] & MP_FLOATINGPOINTER_FEATUREBYTE2_PICMODE ) { kPrintf( "(PIC Mode Support)\n" ); } else { kPrintf( "(Virtual Wire Mode Support)\n" ); } //========================================================================== // MP 설정 테이블 헤더 정보를 출력 //========================================================================== kPrintf( "\n=============== MP Configuration Table Header ===============\n" ); pstMPTableHeader = pstMPConfigurationManager->pstMPConfigurationTableHeader; kMemCpy( vcStringBuffer, pstMPTableHeader->vcSignature, 4 ); vcStringBuffer[ 4 ] = '\0'; kPrintf( "Signature : %s\n", vcStringBuffer ); kPrintf( "Length : %d Byte\n", pstMPTableHeader->wBaseTableLength ); kPrintf( "Version : %d\n", pstMPTableHeader->bRevision ); kPrintf( "CheckSum : 0x%X\n", pstMPTableHeader->bCheckSum ); kMemCpy( vcStringBuffer, pstMPTableHeader->vcOEMIDString, 8 ); vcStringBuffer[ 8 ] = '\0'; kPrintf( "OEM ID String : %s\n", vcStringBuffer ); kMemCpy( vcStringBuffer, pstMPTableHeader->vcProductIDString, 12 ); vcStringBuffer[ 12 ] = '\0'; kPrintf( "Product ID String : %s\n", vcStringBuffer ); kPrintf( "OEM Table Pointer : 0x%X\n", pstMPTableHeader->dwOEMTablePointerAddress ); kPrintf( "OEM Table Size : %d Byte\n", pstMPTableHeader->wOEMTableSize ); kPrintf( "Entry Count : %d\n", pstMPTableHeader->wEntryCount ); kPrintf( "Memory Mapped I/O Address Of Local APIC : 0x%X\n", pstMPTableHeader->dwMemoryMapIOAddressOfLocalAPIC ); kPrintf( "Extended Table Length : %d Byte\n", pstMPTableHeader->wExtendedTableLength ); kPrintf( "Extended Table Checksum : 0x%X\n", pstMPTableHeader->bExtendedTableChecksum ); kPrintf( "Press any key to continue... ('q' is exit) : " ); if( kGetCh() == 'q' ) { kPrintf( "\n" ); return ; } kPrintf( "\n" ); //========================================================================== // 기본 MP 설정 테이블 엔트리 정보를 출력 //========================================================================== kPrintf( "\n============= Base MP Configuration Table Entry =============\n" ); qwBaseEntryAddress = pstMPFloatingPointer->dwMPConfigurationTableAddress + sizeof( MPCONFIGURATIONTABLEHEADER ); for( i = 0 ; i < pstMPTableHeader->wEntryCount ; i++ ) { bEntryType = *( BYTE* ) qwBaseEntryAddress; switch( bEntryType ) { // 프로세스 엔트리 정보 출력 case MP_ENTRYTYPE_PROCESSOR: pstProcessorEntry = ( PROCESSORENTRY* ) qwBaseEntryAddress; kPrintf( "Entry Type : Processor\n" ); kPrintf( "Local APIC ID : %d\n", pstProcessorEntry->bLocalAPICID ); kPrintf( "Local APIC Version : 0x%X\n", pstProcessorEntry->bLocalAPICVersion ); kPrintf( "CPU Flags : 0x%X ", pstProcessorEntry->bCPUFlags ); // Enable/Disable 출력 if( pstProcessorEntry->bCPUFlags & MP_PROCESSOR_CPUFLAGS_ENABLE ) { kPrintf( "(Enable, " ); } else { kPrintf( "(Disable, " ); } // BSP/AP 출력 if( pstProcessorEntry->bCPUFlags & MP_PROCESSOR_CPUFLAGS_BSP ) { kPrintf( "BSP)\n" ); } else { kPrintf( "AP)\n" ); } kPrintf( "CPU Signature : 0x%X\n", pstProcessorEntry->vbCPUSignature ); kPrintf( "Feature Flags : 0x%X\n\n", pstProcessorEntry->dwFeatureFlags ); // 프로세스 엔트리의 크기만큼 어드레스를 증가시켜 다음 엔트리로 이동 qwBaseEntryAddress += sizeof( PROCESSORENTRY ); break; // 버스 엔트리 정보 출력 case MP_ENTRYTYPE_BUS: pstBusEntry = ( BUSENTRY* ) qwBaseEntryAddress; kPrintf( "Entry Type : Bus\n" ); kPrintf( "Bus ID : %d\n", pstBusEntry->bBusID ); kMemCpy( vcStringBuffer, pstBusEntry->vcBusTypeString, 6 ); vcStringBuffer[ 6 ] = '\0'; kPrintf( "Bus Type String : %s\n\n", vcStringBuffer ); // 버스 엔트리의 크기만큼 어드레스를 증가시켜 다음 엔트리로 이동 qwBaseEntryAddress += sizeof( BUSENTRY ); break; // I/O APIC 엔트리 case MP_ENTRYTYPE_IOAPIC: pstIOAPICEntry = ( IOAPICENTRY* ) qwBaseEntryAddress; kPrintf( "Entry Type : I/O APIC\n" ); kPrintf( "I/O APIC ID : %d\n", pstIOAPICEntry->bIOAPICID ); kPrintf( "I/O APIC Version : 0x%X\n", pstIOAPICEntry->bIOAPICVersion ); kPrintf( "I/O APIC Flags : 0x%X ", pstIOAPICEntry->bIOAPICFlags ); // Enable/Disable 출력 if( pstIOAPICEntry->bIOAPICFlags == 1 ) { kPrintf( "(Enable)\n" ); } else { kPrintf( "(Disable)\n" ); } kPrintf( "Memory Mapped I/O Address : 0x%X\n\n", pstIOAPICEntry->dwMemoryMapAddress ); // I/O APIC 엔트리의 크기만큼 어드레스를 증가시켜 다음 엔트리로 이동 qwBaseEntryAddress += sizeof( IOAPICENTRY ); break; // I/O 인터럽트 지정 엔트리 case MP_ENTRYTYPE_IOINTERRUPTASSIGNMENT: pstIOAssignmentEntry = ( IOINTERRUPTASSIGNMENTENTRY* ) qwBaseEntryAddress; kPrintf( "Entry Type : I/O Interrupt Assignment\n" ); kPrintf( "Interrupt Type : 0x%X ", pstIOAssignmentEntry->bInterruptType ); // 인터럽트 타입 출력 kPrintf( "(%s)\n", vpcInterruptType[ pstIOAssignmentEntry->bInterruptType ] ); kPrintf( "I/O Interrupt Flags : 0x%X ", pstIOAssignmentEntry->wInterruptFlags ); // 극성과 트리거 모드 출력 kPrintf( "(%s, %s)\n", vpcInterruptFlagsPO[ pstIOAssignmentEntry->wInterruptFlags & 0x03 ], vpcInterruptFlagsEL[ ( pstIOAssignmentEntry->wInterruptFlags >> 2 ) & 0x03 ] ); kPrintf( "Source BUS ID : %d\n", pstIOAssignmentEntry->bSourceBUSID ); kPrintf( "Source BUS IRQ : %d\n", pstIOAssignmentEntry->bSourceBUSIRQ ); kPrintf( "Destination I/O APIC ID : %d\n", pstIOAssignmentEntry->bDestinationIOAPICID ); kPrintf( "Destination I/O APIC INTIN : %d\n\n", pstIOAssignmentEntry->bDestinationIOAPICINTIN ); // I/O 인터럽트 지정 엔트리의 크기만큼 어드레스를 증가시켜 다음 엔트리로 이동 qwBaseEntryAddress += sizeof( IOINTERRUPTASSIGNMENTENTRY ); break; // 로컬 인터럽트 지정 엔트리 case MP_ENTRYTYPE_LOCALINTERRUPTASSIGNMENT: pstLocalAssignmentEntry = ( LOCALINTERRUPTASSIGNMENTENTRY* ) qwBaseEntryAddress; kPrintf( "Entry Type : Local Interrupt Assignment\n" ); kPrintf( "Interrupt Type : 0x%X ", pstLocalAssignmentEntry->bInterruptType ); // 인터럽트 타입 출력 kPrintf( "(%s)\n", vpcInterruptType[ pstLocalAssignmentEntry->bInterruptType ] ); kPrintf( "I/O Interrupt Flags : 0x%X ", pstLocalAssignmentEntry->wInterruptFlags ); // 극성과 트리거 모드 출력 kPrintf( "(%s, %s)\n", vpcInterruptFlagsPO[ pstLocalAssignmentEntry->wInterruptFlags & 0x03 ], vpcInterruptFlagsEL[ ( pstLocalAssignmentEntry->wInterruptFlags >> 2 ) & 0x03 ] ); kPrintf( "Source BUS ID : %d\n", pstLocalAssignmentEntry->bSourceBUSID ); kPrintf( "Source BUS IRQ : %d\n", pstLocalAssignmentEntry->bSourceBUSIRQ ); kPrintf( "Destination Local APIC ID : %d\n", pstLocalAssignmentEntry->bDestinationLocalAPICID ); kPrintf( "Destination Local APIC LINTIN : %d\n\n", pstLocalAssignmentEntry->bDestinationLocalAPICLINTIN ); // 로컬 인터럽트 지정 엔트리의 크기만큼 어드레스를 증가시켜 다음 엔트리로 이동 qwBaseEntryAddress += sizeof( LOCALINTERRUPTASSIGNMENTENTRY ); break; default : kPrintf( "Unknown Entry Type. %d\n", bEntryType ); break; } // 3개를 출력하고 나면 키 입력을 대기 if( ( i != 0 ) && ( ( ( i + 1 ) % 3 ) == 0 ) ) { kPrintf( "Press any key to continue... ('q' is exit) : " ); if( kGetCh() == 'q' ) { kPrintf( "\n" ); return ; } kPrintf( "\n" ); } } }
//============================================================================= // Code for shell //============================================================================= // Main loop void kStartConsoleShell( void ) { char vcCommandBuffer[CONSOLESHELL_MAXCOMMANDBUFFERCOUNT]; int iCommandBufferIndex = 0; BYTE bKey; int iCursorX, iCursorY; // Print prompt kPrintf( CONSOLESHELL_PROMPTMESSAGE ); while( 1 ) { // Wait for key bKey = kGetCh(); // If backspace if ( bKey == KEY_BACKSPACE ) { if ( iCommandBufferIndex > 0 ) { // Get current cursor point, move back on point // print white space, // delete last character in command buffer kGetCursor( &iCursorX, &iCursorY ); kPrintStringXY( iCursorX - 1, iCursorY, " " ); kSetCursor( iCursorX - 1, iCursorY ); iCommandBufferIndex--; } } // Process enter key else if ( bKey == KEY_ENTER ) { kPrintf( "\n" ); if ( iCommandBufferIndex > 0 ) { // Execute command in buffer vcCommandBuffer[iCommandBufferIndex] = '\0'; kExecuteCommand( vcCommandBuffer ); } // Print prompt and Initialize command buffer kPrintf( "%s", CONSOLESHELL_PROMPTMESSAGE ); kMemSet( vcCommandBuffer, '\0', CONSOLESHELL_MAXCOMMANDBUFFERCOUNT ); iCommandBufferIndex = 0; } // Ignore Shift key, Caps lock, Num lock, Scroll lock else if ( ( bKey == KEY_LSHIFT ) || ( bKey == KEY_RSHIFT ) || ( bKey == KEY_CAPSLOCK ) || ( bKey == KEY_NUMLOCK ) || ( bKey == KEY_SCROLLLOCK ) ) { ; } else { // Switch TAB to white space if ( bKey == KEY_TAB ) { bKey = ' '; } // If buffer have room if ( iCommandBufferIndex < CONSOLESHELL_MAXCOMMANDBUFFERCOUNT ) { vcCommandBuffer[iCommandBufferIndex++] = bKey; kPrintf( "%c", bKey ); } } } }
/** * 그래픽 모드를 테스트하는 함수 */ void kStartGraphicModeTest() { VBEMODEINFOBLOCK* pstVBEMode; int iX1, iY1, iX2, iY2; COLOR stColor1, stColor2; int i; char* vpcString[] = { "Pixel", "Line", "Rectangle", "Circle", "MINT64 OS~!!!" }; //========================================================================== // 점, 선, 사각형, 원, 그리고 문자를 간단히 출력 //========================================================================== // (0, 0)에 Pixel이란 문자열을 검은색 바탕에 흰색으로 출력 kDrawText( 0, 0, RGB( 255, 255, 255), RGB( 0, 0, 0 ), vpcString[ 0 ], kStrLen( vpcString[ 0 ] ) ); // 픽셀을 (1, 20), (2, 20)에 흰색으로 출력 kDrawPixel( 1, 20, RGB( 255, 255, 255 ) ); kDrawPixel( 2, 20, RGB( 255, 255, 255 ) ); // (0, 25)에 Line이란 문자열을 검은색 바탕에 빨간색으로 출력 kDrawText( 0, 25, RGB( 255, 0, 0), RGB( 0, 0, 0 ), vpcString[ 1 ], kStrLen( vpcString[ 1 ] ) ); // (20, 50)을 중심으로 (1000, 50) (1000, 100), (1000, 150), (1000, 200), // (1000, 250)까지 빨간색으로 출력 kDrawLine( 20, 50, 1000, 50, RGB( 255, 0, 0 ) ); kDrawLine( 20, 50, 1000, 100, RGB( 255, 0, 0 ) ); kDrawLine( 20, 50, 1000, 150, RGB( 255, 0, 0 ) ); kDrawLine( 20, 50, 1000, 200, RGB( 255, 0, 0 ) ); kDrawLine( 20, 50, 1000, 250, RGB( 255, 0, 0 ) ); // (0, 180)에 Rectangle이란 문자열을 검은색 바탕에 녹색으로 출력 kDrawText( 0, 180, RGB( 0, 255, 0), RGB( 0, 0, 0 ), vpcString[ 2 ], kStrLen( vpcString[ 2 ] ) ); // (20, 200)에서 시작하여 길이가 각각 50, 100, 150, 200인 사각형을 녹색으로 출력 kDrawRect( 20, 200, 70, 250, RGB( 0, 255, 0 ), FALSE ); kDrawRect( 120, 200, 220, 300, RGB( 0, 255, 0 ), TRUE ); kDrawRect( 270, 200, 420, 350, RGB( 0, 255, 0 ), FALSE ); kDrawRect( 470, 200, 670, 400, RGB( 0, 255, 0 ), TRUE ); // (0, 550)에 Circle이란 문자열을 검은색 바탕에 파란색으로 출력 kDrawText( 0, 550, RGB( 0, 0, 255), RGB( 0, 0, 0 ), vpcString[ 3 ], kStrLen( vpcString[ 3 ] ) ); // (45, 600)에서 시작하여 반지름이 25, 50, 75, 100인 원을 파란색으로 출력 kDrawCircle( 45, 600, 25, RGB( 0, 0, 255 ), FALSE ) ; kDrawCircle( 170, 600, 50, RGB( 0, 0, 255 ), TRUE ) ; kDrawCircle( 345, 600, 75, RGB( 0, 0, 255 ), FALSE ) ; kDrawCircle( 570, 600, 100, RGB( 0, 0, 255 ), TRUE ) ; // 키 입력 대기 kGetCh(); //========================================================================== // 점, 선, 사각형, 원, 그리고 문자를 무작위로 출력 //========================================================================== // q 키가 입력될 때까지 아래를 반복 do { // 점 그리기 for( i = 0 ; i < 100 ; i++ ) { // 임의의 X좌표와 색을 반환 kGetRandomXY( &iX1, &iY1 ); stColor1 = kGetRandomColor(); // 점 그리기 kDrawPixel( iX1, iY1, stColor1 ); } // 선 그리기 for( i = 0 ; i < 100 ; i++ ) { // 임의의 X좌표와 색을 반환 kGetRandomXY( &iX1, &iY1 ); kGetRandomXY( &iX2, &iY2 ); stColor1 = kGetRandomColor(); // 선 그리기 kDrawLine( iX1, iY1, iX2, iY2, stColor1 ); } // 사각형 그리기 for( i = 0 ; i < 20 ; i++ ) { // 임의의 X좌표와 색을 반환 kGetRandomXY( &iX1, &iY1 ); kGetRandomXY( &iX2, &iY2 ); stColor1 = kGetRandomColor(); // 사각형 그리기 kDrawRect( iX1, iY1, iX2, iY2, stColor1, kRandom() % 2 ); } // 원 그리기 for( i = 0 ; i < 100 ; i++ ) { // 임의의 X좌표와 색을 반환 kGetRandomXY( &iX1, &iY1 ); stColor1 = kGetRandomColor(); // 원 그리기 kDrawCircle( iX1, iY1, ABS( kRandom() % 50 + 1 ), stColor1, kRandom() % 2 ); } // 텍스트 표시 for( i = 0 ; i < 100 ; i++ ) { // 임의의 X좌표와 색을 반환 kGetRandomXY( &iX1, &iY1 ); stColor1 = kGetRandomColor(); stColor2 = kGetRandomColor(); // 텍스트 출력 kDrawText( iX1, iY1, stColor1, stColor2, vpcString[ 4 ], kStrLen( vpcString[ 4 ] ) ); } } while( kGetCh() != 'q' ); //========================================================================== // 윈도우 프로토타입을 출력 //========================================================================== // q 키를 눌러서 빠져 나왔다면 윈도우 프로토타입을 표시함 while( 1 ) { // 배경을 출력 kDrawRect(0, 0, 1024, 768, RGB( 232, 255, 232 ), TRUE ); // 윈도우 프레임을 3개 그림 for( i = 0 ; i < 3 ; i++ ) { kGetRandomXY( &iX1, &iY1 ); kDrawWindowFrame( iX1, iY1, 400, 200, "MINT64 OS Test Window" ); } kGetCh(); } }