예제 #1
0
파일: Console.c 프로젝트: MSylvia/mint64os
/**
 *  콘솔 초기화
 */
void kInitializeConsole( int iX, int iY )
{
    // 콘솔 자료구조 초기화
    kMemSet( &gs_stConsoleManager, 0, sizeof( gs_stConsoleManager ) );
    // 화면 버퍼 초기화
    kMemSet( &gs_vstScreenBuffer, 0, sizeof( gs_vstScreenBuffer ) );
    
    if( kIsGraphicMode() == FALSE )
    {
        // 그래픽 모드로 시작한 것이 아니면 비디오 메모리를 화면 버퍼로 설정
        gs_stConsoleManager.pstScreenBuffer = ( CHARACTER* ) CONSOLE_VIDEOMEMORYADDRESS;
    }
    else
    {
        // 그래픽 모드로 시작했으면 그래픽 모드용 화면 버퍼를 설정
        gs_stConsoleManager.pstScreenBuffer = gs_vstScreenBuffer;
        
        // 그래픽 모드에서 사용할 키 큐와 뮤텍스를 초기화
        kInitializeQueue( &( gs_stConsoleManager.stKeyQueueForGUI ), gs_vstKeyQueueBuffer, 
                CONSOLE_GUIKEYQUEUE_MAXCOUNT, sizeof( KEYDATA ) );
        kInitializeMutex( &( gs_stConsoleManager.stLock ) );
    }
    
    // 커서 위치 설정
    kSetCursor( iX, iY );
}
예제 #2
0
/**
 *  파라미터를 이용해서 TCB를 설정
 */
void kSetUpTask( TCB* pstTCB, QWORD qwID, QWORD qwFlags, QWORD qwEntryPointAddress,
        void* pvStackAddress, QWORD qwStackSize )
{
    // 콘텍스트 초기화
    kMemSet( pstTCB->stContext.vqRegister, 0, sizeof( pstTCB->stContext.vqRegister ) );
    
    // 스택에 관련된 RSP, RBP 레지스터 설정
    pstTCB->stContext.vqRegister[ TASK_RSPOFFSET ] = ( QWORD ) pvStackAddress + 
            qwStackSize;
    pstTCB->stContext.vqRegister[ TASK_RBPOFFSET ] = ( QWORD ) pvStackAddress + 
            qwStackSize;

    // 세그먼트 셀렉터 설정
    pstTCB->stContext.vqRegister[ TASK_CSOFFSET ] = GDT_KERNELCODESEGMENT;
    pstTCB->stContext.vqRegister[ TASK_DSOFFSET ] = GDT_KERNELDATASEGMENT;
    pstTCB->stContext.vqRegister[ TASK_ESOFFSET ] = GDT_KERNELDATASEGMENT;
    pstTCB->stContext.vqRegister[ TASK_FSOFFSET ] = GDT_KERNELDATASEGMENT;
    pstTCB->stContext.vqRegister[ TASK_GSOFFSET ] = GDT_KERNELDATASEGMENT;
    pstTCB->stContext.vqRegister[ TASK_SSOFFSET ] = GDT_KERNELDATASEGMENT;

    // RIP 레지스터와 인터럽트 플래그 설정
    pstTCB->stContext.vqRegister[ TASK_RIPOFFSET ] = qwEntryPointAddress;

    // RFLAGS 레지스터의 IF 비트(비트 9)를 1로 설정하여 인터럽트 활성화
    pstTCB->stContext.vqRegister[ TASK_RFLAGSOFFSET ] |= 0x0200;
    
    // ID 및 스택, 그리고 플래그 저장
    pstTCB->qwID = qwID;
    pstTCB->pvStackAddress = pvStackAddress;
    pstTCB->qwStackSize = qwStackSize;
    pstTCB->qwFlags = qwFlags;
}
예제 #3
0
/**
 *  TSS 세그먼트의 정보를 초기화
 */
void kInitializeTSSSegment( TSSSEGMENT* pstTSS )
{
    kMemSet( pstTSS, 0, sizeof( TSSSEGMENT ) );
    pstTSS->qwIST[ 0 ] = IST_STARTADDRESS + IST_SIZE;
    // IO 를 TSS의 limit 값보다 크게 설정함으로써 IO Map을 사용하지 않도록 함
    pstTSS->wIOMapBaseAddress = 0xFFFF;
}
예제 #4
0
/**
 *  파라미터를 이용해서 TCB를 설정
 */
static void kSetUpTask( TCB* pstTCB, QWORD qwFlags, QWORD qwEntryPointAddress,
                 void* pvStackAddress, QWORD qwStackSize )
{
    // 콘텍스트 초기화
    kMemSet( pstTCB->stContext.vqRegister, 0, sizeof( pstTCB->stContext.vqRegister ) );
    
    // 스택에 관련된 RSP, RBP 레지스터 설정
    pstTCB->stContext.vqRegister[ TASK_RSPOFFSET ] = ( QWORD ) pvStackAddress + 
            qwStackSize - 8;
    pstTCB->stContext.vqRegister[ TASK_RBPOFFSET ] = ( QWORD ) pvStackAddress + 
            qwStackSize - 8;
    
    // Return Address 영역에 kExitTask() 함수의 어드레스를 삽입하여 태스크의 엔트리
    // 포인트 함수를 빠져나감과 동시에 kExitTask() 함수로 이동하도록 함
    *( QWORD * ) ( ( QWORD ) pvStackAddress + qwStackSize - 8 ) = ( QWORD ) kExitTask;

    // 세그먼트 셀렉터 설정
    pstTCB->stContext.vqRegister[ TASK_CSOFFSET ] = GDT_KERNELCODESEGMENT;
    pstTCB->stContext.vqRegister[ TASK_DSOFFSET ] = GDT_KERNELDATASEGMENT;
    pstTCB->stContext.vqRegister[ TASK_ESOFFSET ] = GDT_KERNELDATASEGMENT;
    pstTCB->stContext.vqRegister[ TASK_FSOFFSET ] = GDT_KERNELDATASEGMENT;
    pstTCB->stContext.vqRegister[ TASK_GSOFFSET ] = GDT_KERNELDATASEGMENT;
    pstTCB->stContext.vqRegister[ TASK_SSOFFSET ] = GDT_KERNELDATASEGMENT;
    
    // RIP 레지스터와 인터럽트 플래그 설정
    pstTCB->stContext.vqRegister[ TASK_RIPOFFSET ] = qwEntryPointAddress;

    // RFLAGS 레지스터의 IF 비트(비트 9)를 1로 설정하여 인터럽트 활성화
    pstTCB->stContext.vqRegister[ TASK_RFLAGSOFFSET ] |= 0x0200;
    
    // 스택과 플래그 저장
    pstTCB->pvStackAddress = pvStackAddress;
    pstTCB->qwStackSize = qwStackSize;
    pstTCB->qwFlags = qwFlags;
}
예제 #5
0
/**
 *  파일 시스템을 초기화
 */
BOOL kInitializeFileSystem( void )
{
    // 자료구조 초기화와 동기화 객체 초기화
    kMemSet( &gs_stFileSystemManager, 0, sizeof( gs_stFileSystemManager ) );
    kInitializeMutex( &( gs_stFileSystemManager.stMutex ) );
    
    // 하드 디스크를 초기화
    if( kInitializeHDD() == TRUE )
    {
        // 초기화가 성공하면 함수 포인터를 하드 디스크용 함수로 설정
        gs_pfReadHDDInformation = kReadHDDInformation;
        gs_pfReadHDDSector = kReadHDDSector;
        gs_pfWriteHDDSector = kWriteHDDSector;
    }
    else
    {
        return FALSE;
    }
    
    // 파일 시스템 연결
    if( kMount() == FALSE )
    {
        return FALSE;
    }
    
    return TRUE;
}
예제 #6
0
파일: FileSystem.c 프로젝트: cocojk/os
// 사용한 핸들을 반환 
static void kFreeFileDirectoryHandle(FILE* pstFile)
{
	// 전체 영역을 초기화 
	kMemSet(pstFile,0,sizeof(FILE));

	// 비어 있는 타입으로 설정 
	pstFile->bType = FILESYSTEM_TYPE_FREE;
}
예제 #7
0
/**
 *  콘솔 초기화
 */
void kInitializeConsole( int iX, int iY )
{
    // 자료구조를 모두 0으로 초기화
    kMemSet( &gs_stConsoleManager, 0, sizeof( gs_stConsoleManager ) );
    
    // 커서 위치 설정
    kSetCursor( iX, iY );
}
예제 #8
0
파일: FileSystem.c 프로젝트: cocojk/os
// 파일을 삭제 
int kRemoveFile(const char* pcFileName)
{
	DIRECTORYENTRY stEntry;
	int iDirectoryEntryOffset;
	int iFileNameLength;

	// 파일 이름 검사 
	iFileNameLength = kStrLen(pcFileName);
	if((iFileNameLength>(sizeof(stEntry.vcFileName)-1))||(iFileNameLength==0))
	{
		return NULL;
	}

	// 동기화 
	kLock(&(gs_stFileSystemManager.stMutex));

	// 파일이 존재하는지 확인 
	iDirectoryEntryOffset = kFindDirectoryEntry(pcFileName,&stEntry);
	if(iDirectoryEntryOffset==-1)
	{
		// 동기화 
		kUnlock(&(gs_stFileSystemManager.stMutex));
		return -1;
	}

	// 다른 태스크에서 해당 파일을 열고 있는지 핸들 풀을 검색하여 확인 파일이 열려 있으면 삭제할 수 없음 
	if(kIsFileOpened(&stEntry)==TRUE)
	{
		// 동기화 
		kUnlock(&(gs_stFileSystemManager.stMutex));
		return -1;
	}

	// 파일을 구성하는 클러스터를 모두 해제 
	if(kFreeClusterUtilEnd(stEntry.dwStartClusterIndex)==FALSE)
	{
		// 동기화 
		kUnlock(&(gs_stFileSystemManager.stMutex));
		return -1;
	}

	// 디렉터리 엔트리를 빈 것으로 설정 
	kMemSet(&stEntry,0,sizeof(stEntry));
	if(kSetDirectoryEntryData(iDirectoryEntryOffset,&stEntry)==FALSE)
	{
		// 동긱화 
		kUnlock(&(gs_stFileSystemManager.stMutex));
		return -1;
	}

	// 동기화 
	kUnlock(&(gs_stFileSystemManager.stMutex));
	return 0;
}
예제 #9
0
/**
 *  태스크 풀 초기화
 */
static void kInitializeTCBPool( void )
{
    int i;
    
    kMemSet( &( gs_stTCBPoolManager ), 0, sizeof( gs_stTCBPoolManager ) );
    
    // 태스크 풀의 어드레스를 지정하고 초기화
    gs_stTCBPoolManager.pstStartAddress = ( TCB* ) TASK_TCBPOOLADDRESS;
    kMemSet( TASK_TCBPOOLADDRESS, 0, sizeof( TCB ) * TASK_MAXCOUNT );

    // TCB에 ID 할당
    for( i = 0 ; i < TASK_MAXCOUNT ; i++ )
    {
        gs_stTCBPoolManager.pstStartAddress[ i ].stLink.qwID = i;
    }
    
    // TCB의 최대 개수와 할당된 횟수를 초기화
    gs_stTCBPoolManager.iMaxCount = TASK_MAXCOUNT;
    gs_stTCBPoolManager.iAllocatedCount = 1;
}
예제 #10
0
/**
 *  TCB를 해제함
 */
static void kFreeTCB( QWORD qwID )
{
    int i;
    
    // 태스크 ID의 하위 32비트가 인덱스 역할을 함
    i = GETTCBOFFSET( qwID );
    
    // TCB를 초기화하고 ID 설정
    kMemSet( &( gs_stTCBPoolManager.pstStartAddress[ i ].stContext ), 0, sizeof( CONTEXT ) );
    gs_stTCBPoolManager.pstStartAddress[ i ].stLink.qwID = i;
    
    gs_stTCBPoolManager.iUseCount--;
}
예제 #11
0
/**
 *  램 디스크의 정보를 반환
 */
BOOL kReadRDDInformation( BOOL bPrimary, BOOL bMaster, 
        HDDINFORMATION* pstHDDInformation )
{
    // 자료구조 초기화
    kMemSet( pstHDDInformation, 0, sizeof( HDDINFORMATION ) );
    
    // 총 섹터 수와 시리얼 번호, 그리고 모델 번호만 설정
    pstHDDInformation->dwTotalSectors = gs_stRDDManager.dwTotalSectorCount;
    kMemCpy( pstHDDInformation->vwSerialNumber, "0000-0000", 9 );
    kMemCpy( pstHDDInformation->vwModelNumber, "MINT RAM Disk v1.0", 18 ); 

    return TRUE;
}
예제 #12
0
/**
 *  파라미터를 이용해서 TCB를 설정
 */
static void kSetUpTask( TCB* pstTCB, QWORD qwFlags, QWORD qwEntryPointAddress,
                 void* pvStackAddress, QWORD qwStackSize )
{
    // 콘텍스트 초기화
    kMemSet( pstTCB->stContext.vqRegister, 0, sizeof( pstTCB->stContext.vqRegister ) );
    
    // 스택에 관련된 RSP, RBP 레지스터 설정
    pstTCB->stContext.vqRegister[ TASK_RSPOFFSET ] = ( QWORD ) pvStackAddress + 
            qwStackSize - 8;
    pstTCB->stContext.vqRegister[ TASK_RBPOFFSET ] = ( QWORD ) pvStackAddress + 
            qwStackSize - 8;
    
    // Return Address 영역에 kExitTask() 함수의 어드레스를 삽입하여 태스크의 엔트리
    // 포인트 함수를 빠져나감과 동시에 kExitTask() 함수로 이동하도록 함
    *( QWORD * ) ( ( QWORD ) pvStackAddress + qwStackSize - 8 ) = ( QWORD ) kExitTask;

    // 세그먼트 셀렉터 설정
    // 커널 태스크인 경우는 커널 레벨 세그먼트 디스크립터를 설정
    if( ( qwFlags & TASK_FLAGS_USERLEVEL ) == 0 )
    {
        pstTCB->stContext.vqRegister[ TASK_CSOFFSET ] = GDT_KERNELCODESEGMENT | SELECTOR_RPL_0;
        pstTCB->stContext.vqRegister[ TASK_DSOFFSET ] = GDT_KERNELDATASEGMENT | SELECTOR_RPL_0;
        pstTCB->stContext.vqRegister[ TASK_ESOFFSET ] = GDT_KERNELDATASEGMENT | SELECTOR_RPL_0;
        pstTCB->stContext.vqRegister[ TASK_FSOFFSET ] = GDT_KERNELDATASEGMENT | SELECTOR_RPL_0;
        pstTCB->stContext.vqRegister[ TASK_GSOFFSET ] = GDT_KERNELDATASEGMENT | SELECTOR_RPL_0;
        pstTCB->stContext.vqRegister[ TASK_SSOFFSET ] = GDT_KERNELDATASEGMENT | SELECTOR_RPL_0;
    }
    // 유저 태스크인 경우는 유저 레벨 세그먼트 디스크립터를 설정
    else
    {
        pstTCB->stContext.vqRegister[ TASK_CSOFFSET ] = GDT_USERCODESEGMENT | SELECTOR_RPL_3;
        pstTCB->stContext.vqRegister[ TASK_DSOFFSET ] = GDT_USERDATASEGMENT | SELECTOR_RPL_3;
        pstTCB->stContext.vqRegister[ TASK_ESOFFSET ] = GDT_USERDATASEGMENT | SELECTOR_RPL_3;
        pstTCB->stContext.vqRegister[ TASK_FSOFFSET ] = GDT_USERDATASEGMENT | SELECTOR_RPL_3;
        pstTCB->stContext.vqRegister[ TASK_GSOFFSET ] = GDT_USERDATASEGMENT | SELECTOR_RPL_3;
        pstTCB->stContext.vqRegister[ TASK_SSOFFSET ] = GDT_USERDATASEGMENT | SELECTOR_RPL_3;
    }
    
    // RIP 레지스터와 인터럽트 플래그 설정
    pstTCB->stContext.vqRegister[ TASK_RIPOFFSET ] = qwEntryPointAddress;

    // RFLAGS 레지스터의 IF 비트(비트 9)를 1로 설정하여 인터럽트 활성화하고
    // IOPL 비트(비트 12~13)를 3으로 설정하여 유저 레벨에서도 I/O 포트에 접근할 수 있도록 함
    pstTCB->stContext.vqRegister[ TASK_RFLAGSOFFSET ] |= 0x3200;
    
    // 스택과 플래그 저장
    pstTCB->pvStackAddress = pvStackAddress;
    pstTCB->qwStackSize = qwStackSize;
    pstTCB->qwFlags = qwFlags;
}
예제 #13
0
/**
 *  램 디스크 디바이스 드라이버 초기화 함수
 */
BOOL kInitializeRDD( DWORD dwTotalSectorCount )
{
    // 자료구조 초기화
    kMemSet( &gs_stRDDManager, 0, sizeof( gs_stRDDManager ) );
    
    // 램 디스크로 사용할 메모리를 할당
    gs_stRDDManager.pbBuffer = ( BYTE* ) kAllocateMemory( dwTotalSectorCount * 512 );
    if( gs_stRDDManager.pbBuffer == NULL )
    {
        return FALSE;
    }
    
    // 총 섹터 수와 동기화 객체를 설정
    gs_stRDDManager.dwTotalSectorCount = dwTotalSectorCount;
    kInitializeMutex( &( gs_stRDDManager.stMutex ) );
    return TRUE;
}
예제 #14
0
/**
 *  TSS 세그먼트의 정보를 초기화
 */
void kInitializeTSSSegment( TSSSEGMENT* pstTSS )
{
    int i;
    
    // 최대 프로세서 또는 코어의 수만큼 루프를 돌면서 생성
    for( i = 0 ; i < MAXPROCESSORCOUNT ; i++ )
    {
        // 0으로 초기화
        kMemSet( pstTSS, 0, sizeof( TSSSEGMENT ) );

        // IST의 뒤에서부터 잘라서 할당함. (주의, IST는 16바이트 단위로 정렬해야 함)
        pstTSS->qwIST[ 0 ] = IST_STARTADDRESS + IST_SIZE - 
            ( IST_SIZE / MAXPROCESSORCOUNT * i );
        
        // IO Map의 기준 주소를 TSS 디스크립터의 Limit 필드보다 크게 설정함으로써 
        // IO Map을 사용하지 않도록 함
        pstTSS->wIOMapBaseAddress = 0xFFFF;

        // 다음 엔트리로 이동
        pstTSS++;
    }
}
예제 #15
0
파일: FileSystem.c 프로젝트: cocojk/os
// 파일을 Count만큼 0으로 채움 
BOOL kWriteZero(FILE* pstFile,DWORD dwCount)
{	
	BYTE* pbBuffer;
	DWORD dwRemainCount;
	DWORD dwWriteCount;

	// 핸들이 NULL이면 실패 
	if(pstFile==NULL)
	{
		return FALSE;
	}

	// 속도 향상을 위해 메모리를 할당받아 클러스터 단위로 쓰기 수행 메모리를 할당 
	pbBuffer = (BYTE*)kAllocateMemory(FILESYSTEM_CLUSTERSIZE);
	if(pbBuffer==NULL)
	{
		return FALSE;
	}

	// 0으로 채움 
	kMemSet(pbBuffer,0,FILESYSTEM_CLUSTERSIZE);
	dwRemainCount = dwCount;

	// 클러스터 단위로 반복해서 쓰기 수행 
	while(dwRemainCount!=0)
	{
		dwWriteCount = MIN(dwRemainCount,FILESYSTEM_CLUSTERSIZE);
		if(kWriteFile(pbBuffer,1,dwWriteCount,pstFile)!=dwWriteCount)
		{
			kFreeMemory(pbBuffer);
			return FALSE;
		}

		dwRemainCount ==dwWriteCount;
	}

	kFreeMemory(pbBuffer);
	return TRUE;
}
예제 #16
0
파일: FileSystem.c 프로젝트: cocojk/os
// 파일 시스템을 초기화 
BOOL kInitializeFileSystem(void)
{
	BOOL bCacheEnable = FALSE;

	// 자료구조 초기화와 동기화 객체 초기화 
	kMemSet(&gs_stFileSystemManager,0,sizeof(gs_stFileSystemManager));
	kInitializeMutex(&(gs_stFileSystemManager.stMutex));

	/*
	// 하드 디스크를 초기화 
	if(kInitializeHDD()==TRUE)
	{
		// 초기화가 성공하면 함수 포인터를 하드 디스크용 함수로 설정 
		gs_pfReadHDDInformation = kReadHDDInformation;
		gs_pfReadHDDSector = kReadHDDSector;
		gs_pfWriteHDDSector = kWriteHDDSector;
	
		// 캐시를 활성화함 
		bCacheEnable = TRUE;
	}
	else*/ if(kInitializeRDD(RDD_TOTALSECTORCOUNT)==TRUE)
	{
		// 초기화가 성공하면 함수 포인터를 램디스크요여 함수로 설정 
		gs_pfReadHDDInformation = kReadRDDInformation;
		gs_pfReadHDDSector = kReadRDDSector;
		gs_pfWriteHDDSector = kWriteRDDSector;

		// 램 디스크는 데이터가 남아 있지 않으므로 매번 파일 시스템을 생성함 
		if(kFormat() == FALSE)
		{
			return FALSE;
		}
	}
	else 
	{
		return FALSE;
	}

	// 파일 시스템 연결 
	if(kMount()==FALSE)
	{
		return FALSE;
	}

	// 핸들을 위한 공간을 할당 
	gs_stFileSystemManager.pstHandlePool = (FILE*) kAllocateMemory(FILESYSTEM_HANDLE_MAXCOUNT*sizeof(FILE));

	// 메모리 할당이 실패하면 하드 디스크가 인식되지 않은 것으로 설정 
	if(gs_stFileSystemManager.pstHandlePool == NULL)
	{
		gs_stFileSystemManager.bMounted = FALSE;
		return FALSE;
	}

	// 핸들 풀을 모두 0으로 설정하여 초기화 
	kMemSet(gs_stFileSystemManager.pstHandlePool,0,FILESYSTEM_HANDLE_MAXCOUNT*sizeof(FILE));

	if(bCacheEnable==TRUE)
	{
		gs_stFileSystemManager.bCacheEnable=kInitializeCacheManager();
	}

	return TRUE;
}
예제 #17
0
파일: FileSystem.c 프로젝트: cocojk/os
// 하드 디스크에 파일 시스템을 생성 
BOOL kFormat(void)
{
	HDDINFORMATION* pstHDD;
	MBR* pstMBR;
	DWORD dwTotalSectorCount,dwRemainSectorCount;
	DWORD dwMaxClusterCount,dwClusterCount;
	DWORD dwClusterLinkSectorCount;
	DWORD i;

	// 동기화 처리 
	kLock(&(gs_stFileSystemManager.stMutex));
	//=========================================================================================
	// 하드 디스크 정보를 읽어서 메타 영역의 크기와 클러스터의 개수를 계산 
	//=========================================================================================
	// 하드 디스크의 정보를 얻어서 하드 디스크의 총 섹터 수를 구함 
	pstHDD = (HDDINFORMATION*)gs_vbTempBuffer;
	if(gs_pfReadHDDInformation(TRUE,TRUE,pstHDD)==FALSE)
	{
		// 동기화 처리 
		kUnlock(&(gs_stFileSystemManager.stMutex));
		return FALSE;
	}

	dwTotalSectorCount = pstHDD->dwTotalSectors;

	// 전체 섹터 수를 4KB, 즉 클러스터 크기로 나누어 최대 클러스터 수를 계산 
	dwMaxClusterCount = dwTotalSectorCount / FILESYSTEM_SECTORPERCLUSTER;

	// 최대 클러스터의 수에 맞춰 클러스터 링크 테이블의 섹터 수를 계산 
	// 링크 데이터는 4바이트이므로, 한 섹터에는 128개가 들어감. 따라서 총 개수를 
	// 128로 나눈 후 올림하여 클러스터 링크의 섹터 수를 구함 
	dwClusterLinkSectorCount = (dwMaxClusterCount+127)/128;

	// 예약된 영역은 현재 사용하지 않으므로, 디스크 전체 영역에서 MBR 영역과 클러스터 
	// 링크 테이블 영역의 크기를 뺀 나머지가 실제 데이터 영역이 됨 
	// 해당 영역을 클러스터 크기로 나누어 실제 클러스터의 개수를 구함 
	dwRemainSectorCount = dwTotalSectorCount - dwClusterLinkSectorCount -1;
	dwClusterCount = dwRemainSectorCount/FILESYSTEM_SECTORPERCLUSTER;

	// 실제 사용 가능한 클러스터 수에 맞춰 다시 한 번 계산 
	dwClusterLinkSectorCount = (dwClusterCount+127)/128;

	//=========================================================================================
	// 계산된 정보를 MBR에 덮어 쓰고, 루트 디렉터리 영역까지 모두 0으로 초기화하여
	// 파일 시스템을 생성 
	//=========================================================================================
	// MBR 영역 읽기 
	if(gs_pfReadHDDSector(TRUE,TRUE,0,1,gs_vbTempBuffer)==FALSE)
	{
		// 동기화 처리 
		kUnlock(&(gs_stFileSystemManager.stMutex));
		return FALSE;
	}

	// 파티션 정보와 파일 시스템 정보 설정 
	pstMBR = (MBR*)gs_vbTempBuffer;
	kMemSet(pstMBR->vstPartiton,0,sizeof(pstMBR->vstPartiton));
	pstMBR->dwSignature = FILESYSTEM_SIGNATUR;
	pstMBR->dwReservedSectorCount = 0;
	pstMBR->dwClusterLinkSectorCount = dwClusterLinkSectorCount;
	pstMBR->dwTotalClusterCount = dwClusterCount;

	// MBR 영역에 1 섹터를 씀 
	if(gs_pfWriteHDDSector(TRUE,TRUE,0,1,gs_vbTempBuffer)==FALSE)
	{
		// 동기화 처리 
		kUnlock(&(gs_stFileSystemManager.stMutex));
		return FALSE;
	}

	// MBR 이후부터 루트 디렉터리까지 모두 0으로 초기화 
	kMemSet(gs_vbTempBuffer,0,512);
	for(i=0;i<(dwClusterLinkSectorCount+FILESYSTEM_SECTORPERCLUSTER);i++)
	{
		// 루트 디렉터리(클러스터 0)는 이미 파일 시스템이 사용하고 있으므로, 할당된 것으로 표시 
		if(i==0)
		{
			((DWORD*)(gs_vbTempBuffer))[0]=FILESYSTEM_LASTCLUSTER;
		}
		else
		{
			((DWORD*)(gs_vbTempBuffer))[0]=FILESYSTEM_FREECLUSTER;
		}

		// 1섹터씩 씀 
		if(gs_pfWriteHDDSector(TRUE,TRUE,i+1,1,gs_vbTempBuffer)==FALSE)
		{
			// 동기화 처리 
			kUnlock(&(gs_stFileSystemManager.stMutex));
			return FALSE;
		}
	}

	// 캐시 버퍼를 모두 버림 
	if(gs_stFileSystemManager.bCacheEnable==TRUE)
	{
		kDiscardAllCacheBuffer(CACHE_CLUSTERLINKTABLEAREA);
		kDiscardAllCacheBuffer(CACHE_DATAAREA);
	}

	// 동기화 처리 
	kUnlock(&(gs_stFileSystemManager.stMutex));
	return TRUE;
}
예제 #18
0
/**
 *  파일 시스템 캐시를 초기화
 */
BOOL kInitializeCacheManager( void )
{
    int i;
    
    // 자료구조 초기화
    kMemSet( &gs_stCacheManager, 0, sizeof( gs_stCacheManager ) );
    
    // 접근 시간 초기화
    gs_stCacheManager.vdwAccessTime[ CACHE_CLUSTERLINKTABLEAREA ] = 0;
    gs_stCacheManager.vdwAccessTime[ CACHE_DATAAREA ] = 0;

    // 캐시 버퍼의 최댓값 설정
    gs_stCacheManager.vdwMaxCount[ CACHE_CLUSTERLINKTABLEAREA ] = 
        CACHE_MAXCLUSTERLINKTABLEAREACOUNT;
    gs_stCacheManager.vdwMaxCount[ CACHE_DATAAREA ] = CACHE_MAXDATAAREACOUNT;
    
    // 클러스터 링크 테이블 영역용 메모리 할당, 클러스터 링크 테이블은 512바이트로 관리함
    gs_stCacheManager.vpbBuffer[ CACHE_CLUSTERLINKTABLEAREA ] = 
        ( BYTE* ) kAllocateMemory( CACHE_MAXCLUSTERLINKTABLEAREACOUNT * 512 );
    if( gs_stCacheManager.vpbBuffer[ CACHE_CLUSTERLINKTABLEAREA ] == NULL )
    {
        return FALSE;
    }
    
    // 할당 받은 메모리 영역을 나누어서 캐시 버퍼에 등록
    for( i = 0 ; i < CACHE_MAXCLUSTERLINKTABLEAREACOUNT ; i++ )
    {
        // 캐시 버퍼에 메모리 공간 할당
        gs_stCacheManager.vvstCacheBuffer[ CACHE_CLUSTERLINKTABLEAREA ][ i ].
            pbBuffer = gs_stCacheManager.vpbBuffer[ CACHE_CLUSTERLINKTABLEAREA ] 
            + ( i * 512 );
        
        // 태그를 유효하지 않은 것으로 설정하여 빈 것으로 만듦
        gs_stCacheManager.vvstCacheBuffer[ CACHE_CLUSTERLINKTABLEAREA ][ i ].
            dwTag = CACHE_INVALIDTAG;
        
    }
    
    // 데이터 영역용 메모리 할당, 데이터 영역은 클러스터 단위(4 Kbyte)로 관리함
    gs_stCacheManager.vpbBuffer[ CACHE_DATAAREA ] = 
        ( BYTE* ) kAllocateMemory( CACHE_MAXDATAAREACOUNT * FILESYSTEM_CLUSTERSIZE );
    if( gs_stCacheManager.vpbBuffer[ CACHE_DATAAREA ] == NULL )
    {
        // 실패하면 이전에 할당 받은 메모리를 해제해야 함
        kFreeMemory( gs_stCacheManager.vpbBuffer[ CACHE_CLUSTERLINKTABLEAREA ] );
        return FALSE;
    }
    
    // 할당 받은 메모리 영역을 나누어서 캐시 버퍼에 등록
    for( i = 0 ; i < CACHE_MAXDATAAREACOUNT ; i++ )
    {
        // 캐시 버퍼에 메모리 공간 할당
        gs_stCacheManager.vvstCacheBuffer[ CACHE_DATAAREA ][ i ].pbBuffer = 
            gs_stCacheManager.vpbBuffer[ CACHE_DATAAREA ] + 
            ( i * FILESYSTEM_CLUSTERSIZE );
        
        // 태그를 유효하지 않은 것으로 설정하여 빈 것으로 만듦
        gs_stCacheManager.vvstCacheBuffer[ CACHE_DATAAREA ][ i ].dwTag = 
            CACHE_INVALIDTAG;
    }
    
    return TRUE;
}
예제 #19
0
//=============================================================================
// 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 );
			}
		}
	}
}
예제 #20
0
/**
 *  현재 생성된 모든 태스크의 정보를 출력
 */
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 );
        }
    }
}
예제 #21
0
/**
 *  셸의 메인 루프
 */
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 );
            }
        }
    }
}
예제 #22
0
/**
 *  MP 설정 테이블을 분석해서 필요한 정보를 저장하는 함수
 */
BOOL kAnalysisMPConfigurationTable( void )
{
    QWORD qwMPFloatingPointerAddress;
    MPFLOATINGPOINTER* pstMPFloatingPointer;
    MPCONFIGURATIONTABLEHEADER* pstMPConfigurationHeader;
    BYTE bEntryType;
    WORD i;
    QWORD qwEntryAddress;
    PROCESSORENTRY* pstProcessorEntry;
    BUSENTRY* pstBusEntry;
    
    // 자료구조 초기화
    kMemSet( &gs_stMPConfigurationManager, 0, sizeof( MPCONFIGRUATIONMANAGER ) );
    gs_stMPConfigurationManager.bISABusID = 0xFF;
    
    // MP 플로팅 포인터의 어드레스를 구함
    if( kFindMPFloatingPointerAddress( &qwMPFloatingPointerAddress ) == FALSE )
    {
        return FALSE;
    }
    
    // MP 플로팅 테이블 설정
    pstMPFloatingPointer = ( MPFLOATINGPOINTER* ) qwMPFloatingPointerAddress;
    gs_stMPConfigurationManager.pstMPFloatingPointer = pstMPFloatingPointer;
    pstMPConfigurationHeader = ( MPCONFIGURATIONTABLEHEADER* ) 
        ( ( QWORD ) pstMPFloatingPointer->dwMPConfigurationTableAddress & 0xFFFFFFFF );
    
    // PIC 모드 지원 여부 저장
    if( pstMPFloatingPointer->vbMPFeatureByte[ 1 ] & 
            MP_FLOATINGPOINTER_FEATUREBYTE2_PICMODE )
    {
        gs_stMPConfigurationManager.bUsePICMode = TRUE;
    }    
    
    // MP 설정 테이블 헤더와 기본 MP 설정 테이블 엔트리의 시작 어드레스 설정
    gs_stMPConfigurationManager.pstMPConfigurationTableHeader = 
        pstMPConfigurationHeader;
    gs_stMPConfigurationManager.qwBaseEntryStartAddress = 
        pstMPFloatingPointer->dwMPConfigurationTableAddress + 
        sizeof( MPCONFIGURATIONTABLEHEADER );
    
    // 모든 엔트리를 돌면서 프로세서의 코어 수를 계산하고 ISA 버스를 검색하여 ID를 저장
    qwEntryAddress = gs_stMPConfigurationManager.qwBaseEntryStartAddress;
    for( i = 0 ; i < pstMPConfigurationHeader->wEntryCount ; i++ )
    {
        bEntryType = *( BYTE* ) qwEntryAddress;
        switch( bEntryType )
        {
            // 프로세서 엔트리이면 프로세서의 수를 하나 증가시킴
        case MP_ENTRYTYPE_PROCESSOR:
            pstProcessorEntry = ( PROCESSORENTRY* ) qwEntryAddress;
            if( pstProcessorEntry->bCPUFlags & MP_PROCESSOR_CPUFLAGS_ENABLE )
            {
                gs_stMPConfigurationManager.iProcessorCount++;
            }
            qwEntryAddress += sizeof( PROCESSORENTRY );
            break;
            
            // 버스 엔트리이면 ISA 버스인지 확인하여 저장
        case MP_ENTRYTYPE_BUS:
            pstBusEntry = ( BUSENTRY* ) qwEntryAddress;
            if( kMemCmp( pstBusEntry->vcBusTypeString, MP_BUS_TYPESTRING_ISA,
                    kStrLen( MP_BUS_TYPESTRING_ISA ) ) == 0 )
            {
                gs_stMPConfigurationManager.bISABusID = pstBusEntry->bBusID;
            }
            qwEntryAddress += sizeof( BUSENTRY );
            break;
            
            // 기타 엔트리는 무시하고 이동
        case MP_ENTRYTYPE_IOAPIC:
        case MP_ENTRYTYPE_IOINTERRUPTASSIGNMENT:
        case MP_ENTRYTYPE_LOCALINTERRUPTASSIGNMENT:
        default:
            qwEntryAddress += 8;
            break;
        }
    }
    return TRUE;
}
예제 #23
0
/**
 *  시스템의 상태를 감시하여 화면에 표시하는 태스크
 */
void kSystemMonitorTask( void )
{
    QWORD qwWindowID;
    int i;
    int iWindowWidth;
    int iProcessorCount;
    DWORD vdwLastCPULoad[ MAXPROCESSORCOUNT ];
    int viLastTaskCount[ MAXPROCESSORCOUNT ];
    QWORD qwLastTickCount;
    EVENT stReceivedEvent;
    WINDOWEVENT* pstWindowEvent;
    BOOL bChanged;
    RECT stScreenArea;
    QWORD qwLastDynamicMemoryUsedSize;
    QWORD qwDynamicMemoryUsedSize;
    QWORD qwTemp;
    
    //--------------------------------------------------------------------------
    // 그래픽 모드 판단
    //--------------------------------------------------------------------------
    // MINT64 OS가 그래픽 모드로 시작했는지 확인
    if( kIsGraphicMode() == FALSE )
    {        
        // MINT64 OS가 그래픽 모드로 시작하지 않았다면 실패
        kPrintf( "This task can run only GUI mode~!!!\n" );
        return ;
    }

    //--------------------------------------------------------------------------
    // 윈도우를 생성
    //--------------------------------------------------------------------------
    // 화면 영역의 크기를 반환
    kGetScreenArea( &stScreenArea );
    
    // 현재 프로세서의 개수로 윈도우의 너비를 계산
    iProcessorCount = kGetProcessorCount();
    iWindowWidth = iProcessorCount * ( SYSTEMMONITOR_PROCESSOR_WIDTH + 
            SYSTEMMONITOR_PROCESSOR_MARGIN ) + SYSTEMMONITOR_PROCESSOR_MARGIN;
    
    // 윈도우를 화면 가운데에 생성한 뒤 화면에 표시하지 않음. 프로세서 정보와 메모리 정보를 
    // 표시하는 영역을 그린 뒤 화면에 표시
    qwWindowID = kCreateWindow( ( stScreenArea.iX2 - iWindowWidth ) / 2, 
        ( stScreenArea.iY2 - SYSTEMMONITOR_WINDOW_HEIGHT ) / 2, 
        iWindowWidth, SYSTEMMONITOR_WINDOW_HEIGHT, WINDOW_FLAGS_DEFAULT & 
        ~WINDOW_FLAGS_SHOW, "System Monitor" );
    // 윈도우를 생성하지 못했으면 실패
    if( qwWindowID == WINDOW_INVALIDID )
    {
        return ;
    }

    // 프로세서 정보를 표시하는 영역을 3픽셀 두께로 표시하고 문자열을 출력
    kDrawLine( qwWindowID, 5, WINDOW_TITLEBAR_HEIGHT + 15, iWindowWidth - 5, 
            WINDOW_TITLEBAR_HEIGHT + 15, RGB( 0, 0, 0 ) );
    kDrawLine( qwWindowID, 5, WINDOW_TITLEBAR_HEIGHT + 16, iWindowWidth - 5, 
            WINDOW_TITLEBAR_HEIGHT + 16, RGB( 0, 0, 0 ) );
    kDrawLine( qwWindowID, 5, WINDOW_TITLEBAR_HEIGHT + 17, iWindowWidth - 5, 
            WINDOW_TITLEBAR_HEIGHT + 17, RGB( 0, 0, 0 ) );
    kDrawText( qwWindowID, 9, WINDOW_TITLEBAR_HEIGHT + 8, RGB( 0, 0, 0 ), 
            WINDOW_COLOR_BACKGROUND, "Processor Information", 21 );


    // 메모리 정보를 표시하는 영역을 3픽셀 두께로 표시하고 문자열을 출력
    kDrawLine( qwWindowID, 5, WINDOW_TITLEBAR_HEIGHT + SYSTEMMONITOR_PROCESSOR_HEIGHT + 50, 
            iWindowWidth - 5, WINDOW_TITLEBAR_HEIGHT + SYSTEMMONITOR_PROCESSOR_HEIGHT + 50, 
            RGB( 0, 0, 0 ) );
    kDrawLine( qwWindowID, 5, WINDOW_TITLEBAR_HEIGHT + SYSTEMMONITOR_PROCESSOR_HEIGHT + 51, 
                iWindowWidth - 5, WINDOW_TITLEBAR_HEIGHT + SYSTEMMONITOR_PROCESSOR_HEIGHT + 51, 
                RGB( 0, 0, 0 ) );
    kDrawLine( qwWindowID, 5, WINDOW_TITLEBAR_HEIGHT + SYSTEMMONITOR_PROCESSOR_HEIGHT + 52, 
                iWindowWidth - 5, WINDOW_TITLEBAR_HEIGHT + SYSTEMMONITOR_PROCESSOR_HEIGHT + 52, 
                RGB( 0, 0, 0 ) );
    kDrawText( qwWindowID, 9, WINDOW_TITLEBAR_HEIGHT + SYSTEMMONITOR_PROCESSOR_HEIGHT + 43, 
            RGB( 0, 0, 0 ), WINDOW_COLOR_BACKGROUND, "Memory Information", 18 );
    // 윈도우를 화면에 표시
    kShowWindow( qwWindowID, TRUE );
    
    // 루프를 돌면서 시스템 정보를 감시하여 화면에 표시
    qwLastTickCount = 0;
    
    // 마지막으로 측정한 프로세서의 부하와 태스크 수, 그리고 메모리 사용량은 모두 0으로 설정
    kMemSet( vdwLastCPULoad, 0, sizeof( vdwLastCPULoad ) );
    kMemSet( viLastTaskCount, 0, sizeof( viLastTaskCount ) );
    qwLastDynamicMemoryUsedSize = 0;
    
    //--------------------------------------------------------------------------
    // GUI 태스크의 이벤트 처리 루프
    //--------------------------------------------------------------------------
    while( 1 )
    {
        //----------------------------------------------------------------------
        // 이벤트 큐의 이벤트 처리
        //----------------------------------------------------------------------
        // 이벤트 큐에서 이벤트를 수신
        if( kReceiveEventFromWindowQueue( qwWindowID, &stReceivedEvent ) == TRUE )
        {
            // 수신된 이벤트를 타입에 따라 나누어 처리
            switch( stReceivedEvent.qwType )
            {
                // 윈도우 이벤트 처리
            case EVENT_WINDOW_CLOSE:
                //--------------------------------------------------------------
                // 윈도우 닫기 이벤트이면 윈도우를 삭제하고 루프를 빠져나가 태스크를 종료
                //--------------------------------------------------------------
                // 윈도우 삭제
                kDeleteWindow( qwWindowID );
                return ;
                break;
                
                // 그 외 정보
            default:
                break;
            }
        }
        
        // 0.5초마다 한번씩 시스템 상태를 확인
        if( ( kGetTickCount() - qwLastTickCount ) < 500 )
        {
            kSleep( 1 );
            continue;
        }

        // 마지막으로 측정한 시간을 최신으로 업데이트
        qwLastTickCount = kGetTickCount();

        //----------------------------------------------------------------------
        // 프로세서 정보 출력
        //----------------------------------------------------------------------
        // 프로세서 수만큼 부하와 태스크 수를 확인하여 달라진 점이 있으면 화면에 업데이트
        for( i = 0 ; i < iProcessorCount ; i++ )
        {
            bChanged = FALSE;
            
            // 프로세서 부하 검사
            if( vdwLastCPULoad[ i ] != kGetProcessorLoad( i ) )
            {
                vdwLastCPULoad [ i ] = kGetProcessorLoad( i );
                bChanged = TRUE;
            }
            // 태스크 수 검사
            else if( viLastTaskCount[ i ] != kGetTaskCount( i ) )
            {
                viLastTaskCount[ i ] = kGetTaskCount( i );
                bChanged = TRUE;
            }
            
            // 이전과 비교해서 변경 사항이 있으면 화면에 업데이트
            if( bChanged == TRUE )
            {
                // 화면에 현재 프로세서의 부하를 표시 
                kDrawProcessorInformation( qwWindowID, i * SYSTEMMONITOR_PROCESSOR_WIDTH + 
                    ( i + 1 ) * SYSTEMMONITOR_PROCESSOR_MARGIN, WINDOW_TITLEBAR_HEIGHT + 28,
                    i );
            }
        }
        
        //----------------------------------------------------------------------
        // 동적 메모리 정보 출력
        //----------------------------------------------------------------------
        // 동적 메모리의 정보를 반환
        kGetDynamicMemoryInformation( &qwTemp, &qwTemp, &qwTemp, 
                &qwDynamicMemoryUsedSize );
        
        // 현재 동적 할당 메모리 사용량이 이전과 다르다면 메모리 정보를 출력
        if( qwDynamicMemoryUsedSize != qwLastDynamicMemoryUsedSize )
        {
            qwLastDynamicMemoryUsedSize = qwDynamicMemoryUsedSize;
            
            // 메모리 정보를 출력
            kDrawMemoryInformation( qwWindowID, WINDOW_TITLEBAR_HEIGHT + 
                    SYSTEMMONITOR_PROCESSOR_HEIGHT + 60, iWindowWidth );
        }
    }
}
예제 #24
0
/**
 *  GUI 버전의 콘솔 셸 태스크
 */
void kGUIConsoleShellTask( void )
{
    static QWORD s_qwWindowID = WINDOW_INVALIDID;
    int iWindowWidth, iWindowHeight;
    EVENT stReceivedEvent;
    KEYEVENT* pstKeyEvent;
    RECT stScreenArea;
    KEYDATA stKeyData;
    TCB* pstConsoleShellTask;
    QWORD qwConsoleShellTaskID;

    //--------------------------------------------------------------------------
    // 그래픽 모드 판단
    //--------------------------------------------------------------------------
    // MINT64 OS가 그래픽 모드로 시작했는지 확인
    if( kIsGraphicMode() == FALSE )
    {        
        // MINT64 OS가 그래픽 모드로 시작하지 않았다면 실패
        kPrintf( "This task can run only GUI mode~!!!\n" );
        return ;
    }
    
    // GUI 콘솔 셸 윈도우가 존재하면 생성된 윈도우를 최상위로 만들고 태스크 종료
    if( s_qwWindowID != WINDOW_INVALIDID )
    {
        kMoveWindowToTop( s_qwWindowID );
        return ;
    }
    
    //--------------------------------------------------------------------------
    // 윈도우를 생성
    //--------------------------------------------------------------------------
    // 전체 화면 영역의 크기를 반환
    kGetScreenArea( &stScreenArea );
    
    // 윈도우의 크기 설정, 화면 버퍼에 들어가는 문자의 최대 너비와 높이를 고려해서 계산
    iWindowWidth = CONSOLE_WIDTH * FONT_ENGLISHWIDTH + 4;
    iWindowHeight = CONSOLE_HEIGHT * FONT_ENGLISHHEIGHT + WINDOW_TITLEBAR_HEIGHT + 2;
    
    // 윈도우 생성 함수 호출, 화면 가운데에 생성
    s_qwWindowID = kCreateWindow( ( stScreenArea.iX2 - iWindowWidth ) / 2, 
        ( stScreenArea.iY2 - iWindowHeight ) / 2, iWindowWidth, iWindowHeight, 
        WINDOW_FLAGS_DEFAULT, "Console Shell for GUI" );
    // 윈도우를 생성하지 못했으면 실패
    if( s_qwWindowID == WINDOW_INVALIDID )
    {
        return ;
    }

    // 셸 커맨드를 처리하는 콘솔 셸 태스크를 생성
    kSetConsoleShellExitFlag( FALSE );
    pstConsoleShellTask = kCreateTask( TASK_FLAGS_LOW | TASK_FLAGS_THREAD, 0, 0, 
        ( QWORD ) kStartConsoleShell, TASK_LOADBALANCINGID );
    if( pstConsoleShellTask == NULL )
    {
        // 콘솔 셸 태스크 생성에 실패하면 윈도우를 삭제하고 종료
        kDeleteWindow( s_qwWindowID );
        return ;
    }
    // 콘솔 셸 태스크의 ID를 저장
    qwConsoleShellTaskID = pstConsoleShellTask->stLink.qwID;

    // 이전 화면 버퍼를 초기화
    kMemSet( gs_vstPreviousScreenBuffer, 0xFF, sizeof( gs_vstPreviousScreenBuffer ) );
    
    //--------------------------------------------------------------------------
    // GUI 태스크의 이벤트 처리 루프
    //--------------------------------------------------------------------------
    while( 1 )
    {
        // 화면 버퍼의 변경된 내용을 윈도우에 업데이트
        kProcessConsoleBuffer( s_qwWindowID );
        
        // 이벤트 큐에서 이벤트를 수신
        if( kReceiveEventFromWindowQueue( s_qwWindowID, &stReceivedEvent ) == FALSE )
        {
            kSleep( 0 );
            continue;
        }
        
        // 수신된 이벤트를 타입에 따라 나누어 처리
        switch( stReceivedEvent.qwType )
        {
            // 키 이벤트 처리
        case EVENT_KEY_DOWN:
        case EVENT_KEY_UP:
            // 여기에 키보드 이벤트 처리 코드 넣기
            pstKeyEvent = &( stReceivedEvent.stKeyEvent );
            stKeyData.bASCIICode = pstKeyEvent->bASCIICode;
            stKeyData.bFlags = pstKeyEvent->bFlags;
            stKeyData.bScanCode = pstKeyEvent->bScanCode;

            // 키를 그래픽 모드용 키 큐로 삽입하여 셸 태스크의 입력으로 전달
            kPutKeyToGUIKeyQueue( &stKeyData );
            break;

            // 윈도우 이벤트 처리
        case EVENT_WINDOW_CLOSE:
            // 생성한 셸 태스크가 종료되도록 종료 플래그를 설정하고 종료될 때까지 대기
            kSetConsoleShellExitFlag( TRUE );
            while( kIsTaskExist( qwConsoleShellTaskID ) == TRUE )
            {
                kSleep( 1 );
            }
            
            // 윈도우를 삭제하고 윈도우 ID를 초기화
            kDeleteWindow( s_qwWindowID );
            s_qwWindowID = WINDOW_INVALIDID;            
            return ;
            
            break;
            
            // 그 외 정보
        default:
            // 여기에 알 수 없는 이벤트 처리 코드 넣기
            break;
        }
    }
}
예제 #25
0
/**
 *  셸의 메인 루프
 */
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 );
            }
        }
    }
}
예제 #26
0
/**
 *  인터럽트 자료구조 초기화
 */
void kInitializeHandler( void )
{
    kMemSet( &gs_stInterruptManager, 0, sizeof( gs_stInterruptManager ) );
}