Snap8.png   옆의 소스는 https 에서 페이지 정보를 얻어오는 함수이다. wininet 을 이용해서 https 의 소스를 얻어올 수 있다곤 하는데 잘 모르겠더라. 계속 검색중 우연히 찾은 사이트에서 얻은 소스이다. 그 홈페이지는 자체 개발한 라이브러리를 이용해서 쉽게 구현하고 있었다.

// Any string unlock the component for the 1st 30-days.이 부분은 뭘 나타내는지 잘 모르겠다.

'NativeCode > api' 카테고리의 다른 글

HTTP 긁어오기 (소스파일 有)  (0) 2010.03.19
FTP  (0) 2010.03.19
CkLibrary  (1) 2010.03.19
Sendarp 사용법  (0) 2010.03.19
Event  (0) 2010.03.19

인터넷에서 mfc https 를 검색하다 우연히 찾아낸 홈페이지.

유용한 정보가 굉장히 많이 들어있다. ㅋㅋ

http://www.example-code.com/mfc/https_get_with_cert.asp

굉장히 좋더라 일단 가보자ㅋㅋ


'NativeCode > api' 카테고리의 다른 글

FTP  (0) 2010.03.19
HTTPS GET - Download HTML from HTTPS URL  (0) 2010.03.19
Sendarp 사용법  (0) 2010.03.19
Event  (0) 2010.03.19
Deadlock 4가지 조건  (0) 2010.03.19
ULONG   ulMACAddr[2],
ulSize = 6;
LPBYTE pBuffer;

if (SendARP(inet_addr(_T("207.219.70.31")), 0,
ulMACAddr, &ulSize) == NO_ERROR)
{
pBuffer = (LPBYTE) ulMACAddr;

// access the address one byte at a time m_strText.Format("%02X:%02X:%02X:%02X:%02X:%02X\r\n",
pBuffer[0],
pBuffer[1],
pBuffer[2],
pBuffer[3],
pBuffer[4],
pBuffer[5]);

m_edit1.ReplaceSel(m_strText);
}
#include <IPHlpApi.h> 를 잊지 말아야할것

'NativeCode > api' 카테고리의 다른 글

HTTPS GET - Download HTML from HTTPS URL  (0) 2010.03.19
CkLibrary  (1) 2010.03.19
Event  (0) 2010.03.19
Deadlock 4가지 조건  (0) 2010.03.19
Synchronization Function  (0) 2010.03.19

HANDLE CreateEvent(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, 
BOOL bInitialState, LPCTSTR lpName); 

HANDLE OpenEvent(DWORD dwDesiredAccess, BOOL bInheritHandle, LPCTSTR lpName); 

bManualReset은 이벤트가 수동리셋 이벤트(manual)인지 자동리셋 이벤트(automatic)인지 지정하는데 TRUE이면 수동리셋 이벤트가 된다. 
bInitialState가 TRUE이면 이벤트를 생성함과 동시에 신호상태로 만들어 이벤트를 기다리는 쓰레드가 곧바로 실행을 하도록 해준다. 
이벤트도 이름(lpName)을 가지므로 프로세스간의 동기화에 사용될 수 있다. 

또한 이벤트가 임계영역이나 뮤텍스와 다른점은 
대기함수를 사용하지 않고도, 쓰레드에서 임의적으로 신호상태와 비신호상태를 설정할 수 있다는 점이다. 다음 함수를 사용한다. 

BOOL SetEvent(HANDLE hEvent); 
BOOL ResetEvent(HANDLE hEvent);



1. 함수의 원형


    HANDLE WINAPI CreateEvent(LPSECURITY_ATTRIBUTES lpEventAttributes, 
                                          BOOL bManualReset, BOOL bInitialState, LPCTSTR lpName);


2. 함수의 기능
 
    이름이 정해진 또는 이름이 없는 이벤트 객체를 열거나 생성하는 함수이다. 이 객체에
    접근할수 있는 경우를 명시하고 싶다면 CreateEventEx 함수를 사용해야 한다.
   
3. 함수의 매개변수에 대한 설명
 
    3.1 lpEventAttributes
        
        SECURITY_ATTRIBUTES 구조체로 선언된 변수의 주소를 명시한다. 이 매개변수에 NULL을 명시하면 
        생성된 이벤트 핸들은 자식 프로세스에 상속되지 않는다. SECURITY_ATTRIBUTES 구조체의 항목인
        lpSecurityDescript-xor에는 새로운 이벤트의 보안 기술자(security descript-xor)에 대하여 명시하도록 되어있다.
        만약, 이 매개변수에 NULL을 사용하여 보안 기술자에 대한 명시를 하지 않은 경우에는, 새로 생성될
        이벤트 객체에 일반적인 보안 기술자가 명시된걸로 간주한다. 일반적인 보안 기술자의
        ACL(Access Control List)은 현재 로그인되어 있는 사용자의 로그인정보에 있는 ACL을 이용하거나 
        이벤트 객체를 생성한 프로세스의 ACL을 가져와 사용한다.

        ACL에 대한 좀더 자세한 내용은 아래의 항목을 참고하시기 바랍니다.
        http://www.tipssoft.com/bulletin/tb.php/FAQ/15

    3.2 bManualReset
 
        이 매개변수에 TRUE를 명시하면 발생된 이벤트 정보가 계속 유지되는 이벤트 객체를 생성한다. 
        즉, 이벤트 객체에 SetEvent 함수를 이용하여 이벤트를 설정하면 ResetEvent 함수를 호출하여
        해제하기 전까지 계속 이벤트가 발생한 상태로 유지된다.
        반대로 이 매개변수에 FALSE를 명시하면 자동으로 이벤트가 해제되는 이벤트 객체를 생성한다.
        즉, 이벤트를 기다리는 스레드가 이벤트가 발생한 상황을 체크하게 되면 자동으로 이벤트
        정보가 해제된다. 따라서 별도의 ResetEvent 함수를 호출할 필요가 없다.
 
    3.3 bInitialState
 
        이 매개변수가 TRUE라면 이벤트 객체는 이벤트가 발생한 상태로 생성되며 FALSE이면 이벤트가
        발생하지 않은 상태로 생성된다.
 
    3.4 lpName
 
        이 매개변수에는 이벤트 객체에 사용할 이름을 명시한다. 여기에 사용되는 이름의 길이는
        MAX_PATH까지로 제한되며 대소문자를 구별(Tips, tips, tipS는 서로 다른걸로 간주)한다.
        만약, 명시한 이름이 이미 생성된 다른 이벤트 객체에 사용되고 있다면 이미 생성된 객체와
        이벤트 발생정보를 공유하게 된다. 따라서 먼저 만들어진 이벤트 객체의 정보가 우선시
        되기 때문에 현재 사용한 bManualReset(3.2), bInitialState(3.3)에 명시한 정보는 무시된다.
        그리고 lpEventAttributes(3.1)에 NULL이 아닌 보안정보가 명시된 경우, 먼저 생성된 
        이벤트 객체의 보안 기술자에 의해서 사용되어질것인지 결정되며 사용가능하다고
        판단되더라도 해당 구조체의 세부항목인 보안기술자 항목에 명시된 정보는 무시된다.
        따라서 고유한 이벤트 객체를 생성하려면 이벤트 이름을 명시할때 주의해야 한다.

        만약, 이 매개변수에 명시한 이름이 이미 생성된 Semaphore, Mutex, Waitable timer, Job 
        또는 File-mapping 객체에 사용되고 있다면 이 함수는 실패할것이고 정확한 오류체크를
        위해 GetLastError 함수를 호출하면 ERROR_INVALID_HANDLE 값이 반환될 것이다. 
        즉, 하나의 객체는 다른 형식의 객체와 이름을 공유할수 없고 동일한 형식의 객체에서만
        공유여부가 결정되어진다.

        이 매개변수에 NULL을 명시하면 이름없는 이벤트 객체를 생성한다.
        
        추가적으로 객체의 이름을 명시할때, 시스템 전역적으로 객체의 이름을 공유하고 싶다면 
        사용하고자 하는 이름앞에 "Global\"이라는 접두어를 사용하고 현재 세션공간에서만
        사용하고 싶을때에는 "Local\"이라는 접두어를 사용할수 있다.

        "Global" 또는  "Local" 이라는 접두어를 사용할수 있는 커널 객체에 대해서 좀더 자세한 
        내용을 원하신다면 아래 내용을 참고하시기 바랍니다.
        ( Kernal Objcet Namespace ) -http://www.tipssoft.com/bulletin/tb.php/FAQ/17

        그리고 사적인 이름공간에도 이벤트 객체를 생성할수 있는데 이방법에 대해서 좀더
         자세한 내용을 원하신다면 아래 내용을 참고하시기 바랍니다.
         [ Object Namespaces ] - http://www.tipssoft.com/bulletin/tb.php/FAQ/18


4. 함수의 반환값
    
    이 함수가 성공적으로 수행을 완료했다면 생성된 이벤트 객체의 핸들이 반환될 것이다. 만약,
    lpName에 사용한 이름과 동일한 이름으로 생성된 이벤트 객체가 이미 생성되어 있다면
    해당 객체의 핸들이 반환될것이다. 이때, GetLastError 함수를 호출해보면 
    ERROR_ALREADY_EXISTS가 반환될 것이다. 따라서 다른 프로세스와 이벤트 객체가
    공유되는것을 원치 않는다면 CreateEvent 함수가 정상적인 이벤트 핸들값을 반환하더라도
    GetLastError 함수를 호출하여 ERROR_ALREADY_EXISTS 값이 반환되는지를 체크하는것도
    좋은 방법일 것이다.

    만약 함수가 실패한다면 NULL값이 반환될 것이고, GetLastError 함수를 호출해서 좀더 자세한 
    오류 상황을 확인할 수 있다.

'NativeCode > api' 카테고리의 다른 글

CkLibrary  (1) 2010.03.19
Sendarp 사용법  (0) 2010.03.19
Deadlock 4가지 조건  (0) 2010.03.19
Synchronization Function  (0) 2010.03.19
Win Version & Macro  (0) 2010.03.18

개 이상의 프로세스가 각각의 공유 자원을 사용하고 있으면서 다른 자원을 요구하여 무한정 대기하는 상태를 교착상태라 하는데 이는 4가지 반드시 필요한 조건이 있다. 다음의 정리 내용을 확인하자.

교착상태가 일어나기 위한 네 가지 조건(하나라도 만족하지 않으면 일어나지 않음)

상호배제(Mutual Exclusion)

▪공유 자원을 하나의 프로세스만 공유해야 한다.

점유와 대기(Hold and Wait)

▪최소한 하나의 자원을 점유하고 있고, 다른 프로세스가 점유한 자원을 이용하기 위해 대기하는 프로세스가 있어야 한다.

비선점(Non-Preemption)

▪다른 프로세스에 할당된 자원을 강제로 중지할 수 없어야 한다.

환형대기(Circular Wait)

▪공유 자원과 공유 자원을 사용하려는 프로세스가 원형으로 구성되어 자신에게 할당된 자원을 점유하면서 인접한 양쪽 프로세스의 자원을 요구해야 한다.


'NativeCode > api' 카테고리의 다른 글

Sendarp 사용법  (0) 2010.03.19
Event  (0) 2010.03.19
Synchronization Function  (0) 2010.03.19
Win Version & Macro  (0) 2010.03.18
사용법  (0) 2010.03.18

Critical Section

크리티컬 섹션을 사용하는 이유.

속도가 뮤텍스나 세마포어보다 빠르다.

동기화시 가장 주의할 점은 DeadLock이다

한 프로세스 안에서만 사용이 가능하다.


CRITICAL_SECTION m_CriticalSection;

InitializeCriticalSection( &m_CriticalSection );

DeleteCriticalSection( &m_CriticalSection );


EnterCriticalSection( &m_CriticalSection );

LeaveCriticalSection( &m_CriticalSection );



Mutex

뮤텍스는 크리티컬 섹션과 비슷해서 크리티컬 섹션이 쓰이는 곳에 대신 사용할 수 있다.

그리고 이름을 갖고 있으므로 다른 프로세스에서도 사용이 가능하다.

하지만 속도는 더 느리다.


HANDLE hMutex;

hMutex = CreateMutex( NULL, FALSE, NULL );

ReleaseMutext( hMutex );

WaitForSingleObject( hMutex, INFINITE );



Semaphore

세마포어는 뮤텍스와 유사한 동기화 객체이다. 물론 차이점이 있다. 뮤텍스는 하나의 공유 자원을 보호하기 위해 사용하지만 세모포어는 제한된 일정 개수를 가지는 자원을 보호하고 관리한다. 여기서 자원이라 함은 상당히 추상적이지만 그것이 하드웨어일 수도 윈도우 프로세스, 스레드와 같은 소페트웨어적인 것을 수도 있다.

HANDLE hSemaphore = ( HANDLE )CreateSemaphore( NULL, 3, 3, NULL );

WaitForSingleObject( hSemaphore, INFINITE );

ReleaseSemaphore( hSemaphore, 1, NULL );


HANDLE CreateSemaphore( LPSECURTY_ATTRIBUTES lpSemaphoreAttributes, LONG lInitialCount, LONG lMaximumCount, LPCSTR lpName );

lMaximumCount 는 최대 사용 개수 lInitialCount = 초기값


HANDLE OpenSemaphore( DWORD dwDesiredAccess, BOOL bInheritHandle, LPCTSTR lpName );

OpenSemaphore 함수로 세마포어의 핸들을 구할 수 있다.

OpenSemaphore(SYNCHRONIZE, FALSE, "MySemaphore");


BOOL ReleaseSemaphore( HANDLE hSemaphore, LONG lReleaseCount, LPLONG lpPreviousCount );

자원의 사용이 끝난 스레드는 이 함수를 호출하여 사용 종료를 세마포어에 알려야 한다. lReleaseCount 로 자신이 사용한 자원의 개수를 알리는데 하나만 사용했으면 이 값은 1이고 만약 여러개를 사용했으면 사용한 만큼 자원을 풀어줘야 한다. 세번째 함수는 이전 카운트를 리턴받기 위한 참조 인수이다.


파괴 void CloseHandle( HANDLE );


// 세마포어의 카운트를 조사하는 함수

int RetSemaCount( HANDLE hSema )

{   

int result;

int count;

result = WaitForSingleObject( hSema, 0 );

if( result == WAIT_TIMEOUT )

return 0;

ReleaseSemaphore( hSema, 1, &count );

return count +1;

}

'NativeCode > api' 카테고리의 다른 글

Event  (0) 2010.03.19
Deadlock 4가지 조건  (0) 2010.03.19
Win Version & Macro  (0) 2010.03.18
사용법  (0) 2010.03.18
LoadLibrary  (0) 2010.03.18

사용자 요구조건 조사

조사 단계는 시스템의 모습과 임무를 파악하는 단계이다. 이 단계에서 고객은 시스템의 목표 기술문(vision statement) 작성을 담당한다. 목표 기술문은 20~30 단어 정도로 구성되며 전체적인 시스템 메타포의 개발을 이끌 수 있어야 한다. 고개과 개발자는 이 단계에서 함께 일하면서 기술적 옵션, 요구 사항 분석을 조사하며 유저 스토리의 목록을 완성한다.


목표 기술문은 시스템의 목적을 기술하는 추상적인 문장이다. '이 시스템의 목적은 인터넷을 통해 서적을 판매하는 것이다' 와 같은 것이 그 예이다.
시스템 메타포는 팀에서 시스템을 개념화하는 방식이며 보통 비즈니스 분야의 말들로 쓰여진다. "고객이 들어와서 열람, 검색하고 책을 살 수 있는 가상의 서점" 같은 것이 그 예이다.
유저 스토리는 사용자의 요구 사항을 이해하는 하나의 도구이다. 유저 스토리는 사용 실례 같은 것과 비슷하며, 고객에 의해서 비전문적인 용어로 쓰여진다. 보통의 유저 스토리는 3~4 문장 정도의 길이이다.


유저 스토리 작성하기

프로젝트 시작 단계에서 고객은 중요하고 유저 추상적인 유저 스토리를 작성하고 개발자는 해당되는 개발에 필요한 시간을 추정해 본다. 물론 고객과 개발자 서로가 이 상태에서늬 예측은 상당히 추상적인 것이며 앞으로 개발이 진행되면서 이터레이션 단계에서 상세화될 것이라는 생각을 갖고 있다. 어떤 경우에는 개발자들이 좀 더 자세한 예측을 위해서 스파이킹(spiking - 프로토타이핑이나 기술적 연구)을 하는 경우도 있다. 기술 전문가나 컨설턴트가 추상적 수준에서의 타당성 검토나 관련 연구를 도울 수도 있다. 스파이킹은 단순하지만 개발에 필요한 노력과 방법론을 이해하는 데 커다란 도움이 된다.


스파이킹은 프로토타입을 만들면서 조사하는 것이다. 스파이킹은 일반적인 기술 연구에 시간을 들인다기보다는 특정 목적을 갖고 이루어진다.


스파이킹이 끝나면 개발팀이 그에 대한 지식을 얻게 되는 것이고 스파이킹에 사용된 코드는 버려진다. 스파이킹은 수시간에 이루어질 수도 있지만 보통의 경우에는 수일이 걸리게 된다. 작업이 진전되면서 어려운 문제에 대한 스파이킹을 포기하는 경우도 생기는데 이것은 일반적인 상황은 아니다.


스파이킹 기간에 작성된 코드는 보통 재사용할 만큼 품질이 좋지 못해서 버려지는 것이 일반적이다. 스파이킹을 할 때 개발자는 연구의 일환으로 코드를 작성하는 것이지 특정 디자인에 입각해서 짜는 것이 아니기 때문이다.


추정과 발견(Estimating and Discovering)

조사의 단계는 대부분 발견에 관한 것이다. 고객은 그들이 원하는 것은 발견해가고 개발자는 그들의 문제에 대한 접근 방식을 발견해 가면서 또 스파이킹을 통해서 추정을 해나간다. 스파이킹을 하는 데 필요한 시간을 추정하고 실제 드는 시간과 비교하는 것만으로 간단하게 처리된다. 이렇게 해서 조사 단계에서는 개발팀이 좀더 정밀한 추정 기술을 습득하게 하는 장점도 갖게 된다. 이런 기술은 이후 이터레이션 계획이 시작해지면 아주 중요해진다.


'SE > agile' 카테고리의 다른 글

UML: 클래스 다이어그램 기초  (0) 2010.07.08
Observer Pattern  (0) 2010.06.18
02] XP 개발 주기의 개괄  (0) 2010.03.18
01] XP 정의, 4개 구성  (0) 2010.03.18

XP 개발 주기의 개괄

XP에서의 기본 전제는 고객과 개발자가 함께 진정한 가치를 지닌 소프트웨어를 만들어 나간다는 것이다. 고객은 XP 프로젝트의 개발 주기에 따라서 사업적 가치를 창출해내기 위해서 개발팀에 방향을 제시해 준다. 고객이 프로젝트에 능동적으로 참여하는 것이다.


Snap6.jpg 이 그림은 XP 개발 주기가 지속적으로 가치를 정의하고 만들어 가는 과정임을 보여준다. 이 과정은 이전의 패러다임과 다를 것이 하나도 없어 보인다. 모든 개발에서 고객은 가치를 정의하고 개발자는 가치를 만들어 낸다. XP에서의 차이점은 그런 주기가 매우 짧게 일어난다는 것이다. 개발팀은 새로운 기능을 매 분, 매 시간마다 만들어 낸다. 이것이 고객에게 프로젝트를 보완하고 수정할 수 있는 여지를 제공한다.












단계설명
조사 기간 프로젝트 시작, 추상적 수준의 사용자 요구분석, 기술적인 프로토타이핑
계획 작업의 우선순위 부여, 릴리즈 단위로의 분할, 초기 계획 작성
이터레이션(iteration) 시스템의 개발과 테스트, 2차로 작업을 나누어 이터레이션 계획 수립, 실 사용자가 이 단계에서 ㅇ이너페이스를 개량하고 사용 편의성을 확인하기 위해 일할 수 있다.
제품화 고객의 작업 환경에 소프트웨어를 설치
유지 보수 지속적 유지, 보수, 기능 향상


XP 프로젝트는 고객의 제품에 대한 시각을 우선 릴리즈 단위로 나누고 다시 릴리즈를 이터레이션 단위로 나눈다. 계획 단계는 프로젝트가 진행됨에 따라 점차 상세화, 발전되는 과정으로 인식된다.


Snap2(1).jpg 각각의 이터레이션에서 새 코드를 작성해서 통합될 때마다 build가 이루어지게 된다. 빌드의 수는 사용되는 기술의 종류와 팀에서 채택한 개발 스타일에 따라 다르다. 그렇다면 릴리즈와 이터레이션의 주된 차이점은 무엇인가? 릴리즈 단위가 끝날 때면 개발진은 작동하는 소프트웨어를 고객에게 넘겨주는 반면 이터레이션에서는 개발팀 내부적인 확인만 이루어진다. 이런 식으로 개발팀에 상주하는 고객과 개발자 사이에서 프로젝트의 진행 정도를 확인하고 조절하게 된다.





build는 시스템의 구성요소가 하나로 통합되어서 제대로 작동하는지 테스트하는 과정이다.


[그림 4.3]은 XP 가 가진 이터레이션 중심의 특징을 보여준다. 

Snap3(1).jpg 조사 이후에 개발팀은 릴리즈 계획을 세우고 소프트웨어가 완성되어 제품화 준비를 할 때 까지 이터레이션 작업을 계속하게 된다. 제품화나 각 릴리즈의 종료 시점에서는 소프트웨어가 작업 현장에 투입되어서 테스트된다. 제품화는 그 소프트웨어를 사용하여 실제 사업적 가치를 얻기 시작한다는 점에서 중요하다. 제품화가 이루어진 후의 다른 특성은 이제 제품의 문제로 생기는 비용이 훨씬 커진다는 것이다. 이 때문에 신중한 고객들은 최종 점검 테스트를 한다.




'SE > agile' 카테고리의 다른 글

UML: 클래스 다이어그램 기초  (0) 2010.07.08
Observer Pattern  (0) 2010.06.18
① 사용자 요구조건 조사  (0) 2010.03.18
01] XP 정의, 4개 구성  (0) 2010.03.18

1. XP 정의하기

XP는 4개의 부분, 가치, 원칙, 활동, 기법으로 구성된다. XP는 별도로 고안되었다기 보다는 협동, 작업의 흐름, 시스템 속에서 나타났다고 하는 편이 옳을 것이다. 이런 소프트웨어 개발의 유기적인 관점을 유지하면서 XP는 가치와 원칙들에 기반하여 만들어져서 그로부터 기법과 활동을 고안해냈다.


1) 가치

XP는 개발을 위한 공통의 가치(value)에 의해서 이끌어 진다.

가치설명
단순성 XP에서 단순성은 "동작하는 최대한 단순한 작업을 하는 것"으로 정의된다. 당장의 문제를 가급적 단순하게 해결하고 이후의 문제는 그 때 해결될 것이라고 믿는 것이다. 보통의 방법론들은 어느 정도 앞날을 대비한 계획을 세우고 고객은 전체 시스템에 대해서 예상해 보게 된다. 이런 방법론에 깔린 생각은 이후의 수정이 불가능하지는 않더라도 어려울 것이라는 것이다. XP는 당장 고객이 원하는 것을 하는 것으로 관점을 달리한다. XP 그룹들에서 하는 이야기가 있다. "아마 그건 필요 없을껄" 이것이 의미하는 것은 개발팀은 단순한 생각을 갖고 고객이 필요할 것 같은 것이 아니라 고객이 당장 필요로 하는 것을 구현해야 한다는 것이다. 왜 앞으로 필요할 것 같은 기능에 대해서 미리 디자인하는 걸까? 그것은 이후 수정이 일어날 경우 그 비용이 너무 높기 때문이다. 요약하자면, 단순한 시스템이 커뮤니케이션 비용이 적게 들고 통합이 용이하며 더 나은 확장성을 가지고 있다.
커뮤니케이션 모든 방법론은 내부적으로 커뮤니케이션 과정을 가지고 있지만 XP에서는 특별히 핵심 가치로 존재한다. 커뮤니케이션의 초점은 문서나 보고서, 계획서에 있지 않고 대화에 있다. 모든 팀 구성원간의 커뮤니케이션이 없이는 협업은 약해지고, 결국은 실패할 것이다. XP에는 작업에 커뮤니케이션을 요구하는 짝 프로그래밍 같은 기법을 사용한다. 1장 "XP 가 나오게 된 배경"에서 '이해'가 소프트웨어 개발에 얼마나 커다란 어려움인지에 대해서 이미 이야기했다. XP는 이를 인정하고 팀 멤버간의 장벽을 허물기 위해 노력한다. XP 에서 모든 문서는 사람들간의 커뮤니케이션을 돕는 데 쓰인다.
피드백 XP 에서는 모든 시스템에 대한 계속되는 질문에 대한 대답이 지속적이고 구체적인 피드백에 의해 이루어진다. 제품은 시행착오를 거쳐서만이 검증 될 수 있다. 이것은 엄연한 사실이기 때문에 개발팀은 소프트웨어를 빨리 만들어낸 후, 고객에게 데모를 해야 한다.
용기 용기는 빨리 작업하고, 필요시 다시 개발하겠다는 자신감이다. XP 에서의 용기는 다른 세 가지 가치들과 하나의 문맥에서 생각해 보아야 한다. 그만큼 중요한 것이다. 하지만 XP의 용기는 강력하고 자동화된 테스트에 기반한 대단함이지 모르는 것에 대한 무모한 노력은 아니다.


2) 원칙

XP의 핵심 가치를 바탕으로 소프트웨어 개발에 지침이 될 다섯 개의 주요 원칙(Principle) 이다.

원칙설명
피드백은 신속히 신속한 피드백은 개발자가 짧은 단위로 고객의 피드백을 받아서 고객의 요구를 잘 반영하고 있는지 확인하는 것을 의미한다.
단순함을 전제 단순함을 전제하는 것은 문제를 대할 때 간단히 문제가 풀릴 것이라 생각하라는 것이다. 또 그것은 현재 문제에 집중해서 작업하고 미래의 일에 대해서는 걱정하지 말라는 것을 의미한다.
점진적인 수정 문제를 풀 때의 과정을 작은 교정의 연속이라고 생각하라. 이것은 계획, 개발, 디자인에 모두 적용된다. 예를 들어 고객이 이미 웹 사이트를 가지고 있고, 거기에 JSP를 포팅하고 할 경우 XP 팀은 한번에 완성해서 끝내는 것을 목표로 하기 보다는 사업부에서의 요구에 따라서 여러 차례 소규모의 출시를 할 것이다.
변화의 인정 현존하는 문제를 풀면서 옵션의 여지가 있는 방법을 택하라.
고품질의 작업 작업의 품질은 타협의 대상이 아니다. XP는 테스트 위주 프로그래밍으로 그 무엇보다 코드와 테스트의 중요성을 강조한다


3) 활동

지금까지 가치와 원칙들에 대해 알아보았는데, 그렇다면 실제 XP에서 하는 일은 어떤 것 인가? 몇 가지 XP 사이클에서의 활동(Activity)에 대해 알아보자.

활동설명
듣기 XP는 능동적인 듣기를 요구한다. 형식적인 문서에 대한 의존도가 늦은 대신에 고수준의 구두 커뮤니케이션이 요구된다. 단순히 개발자가 고객의 말에 귀기울여야 한다는 것 이상으로 XP는 보다 나은 커뮤니케이션을 지향한다.  문서에 대한 의존 없이 XP 사용자들은 다른 형태의 구두 의사소통을 익히고 능숙해져야 한다.
테스트 XP에서의 테스트는 고객에게 출시하기 전에 하는 작업이 아니라 개발 전 과정에 걸쳐 일어나는 공정의 일부이다. 심지어 개발자는 코드를 작성하기 전에 테스트를 먼저 작성할 정도이다. XP 테스트는 정확성이나 결점을 측정하는 데 국한되는 것이 아니라 제품의 성능이나 적응도까지 점검한다. 코드를 짜기 전에 테스트를 만드는 것은 개발자에게 생각의 전환을 요구한다. 그 결과로 코드는 비용이 많이 드는 개발의 후반부에 별도의 디버깅 과정 없이 그 자체로 높은 품질을 지니게 된다.
디자인

문서화된 디자인이 적은 대신 XP 개발자는 코드를 작성할 때 의도적으로 그 의미를 표현하려 한다. 소스 코드를 읽는 것만으로 다른 팀의 멤버들은 논리와 알고리즘, 흐름을 이해할 수 있다. 여기서 이야기하는 것은 주석에 대한 이야기가 아니라 소스 코드 그 자체가 커뮤니케이션의 수단이 된다는 것임에 주의하기 바란다. 소스코드는 실제 제품에 우리가 가장 가까이 접근할 수 있는 것 이다.

XP의 기초 아이디어 중 하나는 디자인이 프로젝트 전체에 걸쳐서 발전해 나간다는 것이다. 디자인은 멈추어 있거나 특정 단계에서 이루어지는 것이 아니라 팀 기반의 동적인 것이다. 어떤 면에서 소프트웨어는 언제나 디자인 중이라고 이야기할 수도 있다. 디자인 단계를 제한해서 이런 점들을 무시하는 대신 XP는 자연스런 시스템의 발전을 수용한다.


4) 기법

그렇다면, 어떻게 XP의 활동들을 실행에 옮길 수 있을까? XP는 이들 활동들을 12개의 핵심적인 기법(Practice)으로 표현한다. 이 기법들이 XP팀들이 매일 현장에서 시스템을 개발하는 데 사용하는 것들이다.

번호기법설명
1 계획 짜기 게임 계획 짜기 게임의 역할은 빠른 시간 안에 다음의 출시 계획이나 일정을 빨리 세우기 위한 것이다.
2 짧은 릴리즈 XP 개발 사이클은 사업적 가치를 달성하기 위해 짧은 릴리즈로 이루어진다.
3 메타포 메타포는 프로젝트를 표현하는 데 쓰이는 시각적인 것, 단어, 언어이다.
4 단순한 디자인 디자인은 반드시 단순해야 한다. XP에서의 단순함의 의미는 동작하는 것 중에서 가장 단순해야 한다는 것이다.
5 테스트 XP 개발의 핵심은 자동화된 테스트이다. 개발시에는 가장 먼저 테스트부터 작성해야 하고 테스트 툴에 의해서 사용된다.
6 리팩토링 리팩토링은 시스템 외적 동작의 변화 없이 기존 코드의 디자인을 향상시키는 작업이다.
7 짝 프로그래밍 짝 프로그래밍은 두 명의 개발자가 한 컴퓨터 앞에 앉아서 같이 개발작업을 진행하는 것이다.
8 공동 소유 공동 소유는 언제, 누구라도 코드를 수정해서 더 좋게 만들 수 있게 해준다.
9 지속적인 통합 시스템의 부분은 하루에도 수 차례 통합 작업을 거친다.
10 주당 40시간 근무 초과근무가 많은 곳에서는 일괄적인 품질의 유지가 어려워진다. XP는 품질을 위해서 일반 업무시간의 준수를 요구한다.
11 현장의 고객 고객이 현장에 있고 개발팀에 참가한다.
12 코딩 표준 코딩 표준은 모든 개발자가 개발시 지키기로 합의한 약정이다.

아 빡시다. 계속 써놔야한디. 아나ㅋㅋ 언제 다하지...

'SE > agile' 카테고리의 다른 글

UML: 클래스 다이어그램 기초  (0) 2010.07.08
Observer Pattern  (0) 2010.06.18
① 사용자 요구조건 조사  (0) 2010.03.18
02] XP 개발 주기의 개괄  (0) 2010.03.18

typedef struct _CHILD_RESULT
{
 DWORD dwDepth;
 LPVOID  lpLeftContext;
 LPVOID  lpRightContext;
}CHILD_RESULT, *PCHILD_RESULT;

typedef struct _CHECK_RESULT
{
 DWORD    dwFlags;
 DWORD    dwCheckResult;
 CHILD_RESULT  stChildResult;
 TCHAR    szResult[SZ_MAXSIZE];
 LPVOID    lpContext;
}CHECK_RESULT, *PCHECK_RESULT;


1) 구조체 형태 파악하기

0:000> dt _CHECK_RESULT
WinDbg_dt_test!_CHECK_RESULT
   +0x000 dwFlags          : Uint4B
   +0x004 dwCheckResult    : Uint4B
   +0x008 stChildResult    : _CHILD_RESULT
   +0x014 szResult         : [1024] Wchar
   +0x814 lpContext        : Ptr32 Void


2)구조체에 설정된 값 확인하기

0:000> dt _CHECK_RESULT 0x27f6f8
WinDbg_dt_test!_CHECK_RESULT
   +0x000 dwFlags          : 1
   +0x004 dwCheckResult    : 4
   +0x008 stChildResult    : _CHILD_RESULT
   +0x014 szResult         : [1024]  "Check_WinDBG_dt_Command function call"
   +0x814 lpContext        : (null)


2-1)구조체 값 확인하기 (심볼이 설정되었을때)

0:000> dt stChkResult
Local var @ 0x27f6f8 Type _CHECK_RESULT
   +0x000 dwFlags          : 1
   +0x004 dwCheckResult    : 4
   +0x008 stChildResult    : _CHILD_RESULT
   +0x014 szResult         : [1024]  "Check_WinDBG_dt_Command function call"
   +0x814 lpContext        : (null)


3) 구조체 특정 필드 확인하기 
0:000> dt _CHECK_RESULT dwCheckResult
WinDbg_dt_test!_CHECK_RESULT
   +0x004 dwCheckResult : Uint4B


3-1)구조체 특정 필드 값 확인하기 
0:000> dt _CHECK_RESULT dwCheckResult 0x27f6f8
WinDbg_dt_test!_CHECK_RESULT
   +0x004 dwCheckResult : 4
0:000> dt _CHECK_RESULT stChildResult 0x27f6f8
WinDbg_dt_test!_CHECK_RESULT
   +0x008 stChildResult : _CHILD_RESULT


4) 구조체 내에 있는 구조체 값 확인하기

0:000> dt _CHILD_RESULT 0x27f6f8+0x008
WinDbg_dt_test!_CHILD_RESULT
   +0x000 dwDepth          : 0
   +0x004 lpLeftContext    : (null)
   +0x008 lpRightContext   : (null)


5) 구조체에 있는 모든 값 나열(펼처서)해서 보기
0:000> dt -r _CHECK_RESULT 0x27f6f8
WinDbg_dt_test!_CHECK_RESULT
   +0x000 dwFlags          : 1
   +0x004 dwCheckResult    : 4
   +0x008 stChildResult    : _CHILD_RESULT
      +0x000 dwDepth          : 0
      +0x004 lpLeftContext    : (null)
      +0x008 lpRightContext   : (null)
   +0x014 szResult         : [1024]  "Check_WinDBG_dt_Command function call"
   +0x814 lpContext        : (null) 

'scrap' 카테고리의 다른 글

UDP Flooding  (0) 2010.03.19
Denial Of Service  (0) 2010.03.19
명령어1  (0) 2010.03.18
명령어2  (0) 2010.03.18
명령어3  (0) 2010.03.18

1) 커널의 모든 구조체 나열 : dt nt!_* (dt는 data type의 약자이고, nt는 윈도우 nt를 말하는게 아닐런지...ㅎㅎㅎ)

2) 커널의 특정 구조체 나열(인터럽트 관련) : dt nt!_*interrupt*

3) 특정 구조체의 구조 보기 : dt nt!_ktrap_frame

4) 특정 구조체 내의 하부 구조체까지 보는 명령 : dt nt!_ktrap_frame -r

5) 커널 내의 모든 스택 정보 보기 : !stacks 0

6) 시스템에 로드된 디바이스 드라이버 나열 : lm t n(lm은 list module의 약자 인듯...)


7) 전체 IDT(Interrupt Dispatch Table) 나열 : !idt -a

8) 빈번히(?) 호출된 interrupt 나열 : !idt => 어떤 빈도로 나열되는지 모르겠음.


9) 인터럽트 컨트롤러 나열 : !pic, !apic(작동 안함???)

10) io pic(programmable interrupt controller) 나열 : !ioapic


--------------------------------------- crash 분석 ---------------------------------------------------------

11) !analyze -v : 분석 결과 보기

12) kb : crash 당시의 커널 call stack 보기

13) !process -1 0 : crash 당시의 수행 중이던 프로세스

     !process -1 7 : crash 당시의 수행 중이던 프로세스의 상세 정보 출력(7이 상세 정보 출력 옵션임)

     - !process 0 0 : crash 당시의 가상메모리에 load 되어 있던 모든 프로세스(마지막이 0 flag 이므로, 간략히 출력 옵션임)

     - !process [process 시작주소] : 프로세스 관련 상세 정보 출력,

                                                   위의 커맨드로 시작주소를 알 수 있음.

     - 출력 정보 설명 :

        PROCESS : 프로세스의 정보가 들어있는 EPROCESS Block의 주소

        Cid : 프로세스 ID

        Peb : Process Environment Block 의 주소

        ParentCid : 부모 프로세스 ID

        Image : 프로세스 이름


14) !vm : crash 당시의 가상 메모리 사용 내역 요약 및 프로세스 리스트

15) !poolused : crash 당시의 커널 paged&nonpaged pool list

     - !poolused 2 : nonpaged pool 할당량 별로 정렬 후 출력

     - !poolused 4 : paged pool 할당량 별로 정렬 후 출력

16) !thread [thread 시작주소] : !process [process시작주소]를 하면 프로세스에 포함된 thread의 정보가

                                           나와서 확인 가능함.

     - 출력 정보 설명 : teb(thread environment block 시작 주소)

17) !locks : crash 당시 resource lock 정보

18) !handle : crash 당시에 open된 handle 정보 나열

     !handle [프로세스주소] : 해당 프로세스가 소유한 핸들을 출력함

     !handle [프로세스주소] f

19) !stack [프로세스주소] : 프로세스 관련 Stack 정보를 보여줌


--------------------------------------- hang 분석 ------------------------------------------------------

1) !analyze -hang -v : hang 분석을 해줌


--------------------------------------- !analyze -v 해석 ------------------------------------------------------

덤프에 따라, 일부 값은 안 나올수도 있음.


-v(verbose)  옵션은 상세 결과를 출력하게 함


1) FAULTING_IP : fault가 발생했을 때의 명령의 포인터 값

2) BUGCHECK_STR : 발생한 BUGCHECK을 설명하는 문장임.

                               BUGCHECK은 주로 커널 모드 fault와 연관이 있음.

3) DEFAULT_BUCKET_ID : 현재의 fault가 어떤 범주의 fault에 속하는지를 알려줌

4) LAST_CONTROL_TRANSFER : 스택에서 이뤄진 마지막 두 함수 호출을 보여준다.

                                               이들 주소에 ln 명령을 사용하면, 마지막 함수를 확인 가능함.

                                               (ln [주소] : 주소가 나타내는 심볼을 표시함)

5) STACK_TEXT : 스레드의 전체 스택 트레이스를 보여준다.

6) STACK_COMMAND : fault를 유발한 스레드의 stack trace를 구하기 위해 실행된 명령을 보여준다.

                                  ; 는 구분자임.

6) FOLLOWUP_IP : fault를 유발했을 가능성이 가장 큰 명령을 보여줌

7) SYMBOL_NAME : fault가 발생한 심볼의 이름을 보여줌

                              nt!ExDeferredFreePool+540 으로 나오는 것은 심볼이름이 아님. 주소를 나타냄

                              Private Symbol 이 없기 때문에 해당 주소의 구체적인 함수명 같은 심볼을 안 보여줌

                              (MS만 볼 수 있음)

8) FOLLOWUP_NAME : 이 fault를 누가 사후 점검해야 하는지를 나타냄

                                  보통 MachineOwner가 많음

9) IMAGE_NAME : fault가 발생한 이미지의 이름을 나타냄

10) MODULE_NAME : fault를 보이는 모듈의 이름을 나타냄

                              (lmvm [모듈명] 으로 조회 가능)

11) BUCKET_ID : fault가 속하는 문제의 범주를 보여줌

11) FOLLOW_UP : 이 fault에 가장 알맞은 소유자를 보여준다. 소유자를 찾을수 없다면 디폴트인 MachineOwner가 됨.


[출처] windbg 명령어 정리|작성자 난이


'scrap' 카테고리의 다른 글

Denial Of Service  (0) 2010.03.19
dt 명령어  (0) 2010.03.18
명령어2  (0) 2010.03.18
명령어3  (0) 2010.03.18
명렁어4  (0) 2010.03.18

아래 3가지 옵션을 이용하면 보다 많은 정보를 쉽게 확인 할 수 있습니다.

-V : 레지스터 또는 버추얼 메모리 주소 값을 보여 줍니다.

-t : 각 로컬 변수의 data type을 보여 줍니다.

-i : local, global, parameter, function, or unknown 등의 정보를 보여 줍니다.


적용예

1: kd> dv -V -t -i

prv param  b60b6b20 @ebp+0x08 void * P = 0x86558908

prv param  b60b6b24 @ebp+0x0c unsigned long TagToFree = 0

prv local  b60b6b24 @ebp+0x0c struct _EPROCESS * ProcessBilled = 0x00000000

prv local  b60b6b0c @ebp-0x0c unsigned long Tag = 0xb60b6b8d

prv local  b60b6b14 @ebp-0x04 _POOL_TYPE EntryPoolType = PagedPool (1)

prv local  b60b6b08 @ebp-0x10 unsigned long BigPages = 0x805bc066

prv local  b60b6b00 @ebp-0x18 _POOL_TYPE PoolType = NonPagedPool (0)

prv local  b60b6af0 @ebp-0x28 struct _KLOCK_QUEUE_HANDLE LockHandle = struct _KLOCK_QUEUE_HANDLE

prv local  b60b6b20 @ebp+0x08 unsigned long Combined = 0x86558908


로컬 변수인지 또는 파라미터 인지 보여주고 주소값이 나와서 값을 확인해 볼수 있다.


최근에 알게된 Tip을 하나 소개 합니다.

1)특정 콜스택 프레임으로 이동

1: kd> .frame 12

12 013bf554 65e931e8 ipnathlp!NatpDeletePortBlock+0x48


2) 로컬 변수와 파라미터 값 확인

1: kd> dv -V -t

013bf55c @ebp+0x08 struct _NAT_PORT_RESERVATION * PortReservation = 0x0013d1f0

013bf560 @ebp+0x0c struct _NAT_PORT_BLOCK * PortBlock = 0x02f75988

013bf544 @ebp-0x10 struct _IO_STATUS_BLOCK IoStatus = struct _IO_STATUS_BLOCK

013bf54c @ebp-0x08 struct tcp_blockports_request Request = struct tcp_blockports_request


//dt 명령어로 값을 확인했다.

1: kd> dt _NAT_PORT_RESERVATION 0x0013d1f0

ipnathlp!_NAT_PORT_RESERVATION

   +0x000 TcpipHandle      : 0x00000da8

   +0x004 BlockSize        : 0x20

   +0x006 PortBlockSize    : 0x18

   +0x008 PortBlockList    : _LIST_ENTRY [ 0x2f75988 - 0x12b7f8 ]


//dt 명령어로 값을 확인했다.

1: kd> dt _NAT_PORT_BLOCK 0x02f75988

ipnathlp!_NAT_PORT_BLOCK

   +0x000 Link             : _LIST_ENTRY [ 0x12c050 - 0x13d1f8 ]

   +0x008 StartHandle      : 0x1389

   +0x00c Bitmap           : _RTL_BITMAP

   +0x014 BitmapBuffer     : [0] 0


3) ?? 명령으로 특정 로컬 변수값 확인

1: kd> ?? Request  -> (?? 명령어로 확인할수 있는줄 몰랐다, 꼭 dt만 사용해야 하는줄 알았다.)

struct tcp_blockports_request

   +0x000 ReservePorts     : 0

   +0x004 NumberofPorts    : 0x1389

   +0x004 StartHandle      : 0x1389 a 0n5001

'scrap' 카테고리의 다른 글

dt 명령어  (0) 2010.03.18
명령어1  (0) 2010.03.18
명령어3  (0) 2010.03.18
명렁어4  (0) 2010.03.18
명령어5  (0) 2010.03.18

kd> .symfix e:\symbols

kd> .reload
Connected to Windows XP 2600 x86 compatible target, ptr64 FALSE
Loading Kernel Symbols
........................
Loading User Symbols

lm 을 사용하여 심볼이 로드된 상태를 봅니다.

kd> lm
start    end        module name
804d9000 806ede00   nt         (pdb symbols)          e:\symbols\ntoskrnl.pdb\8592B6763F344B562\ntoskrnl.pdb
806ee000 80701d80   hal        (deferred)            
f9871000 f988b580   Mup        (deferred)   
f996f000 f998e780   fltMgr     (deferred)
...

nt 는 심볼이 로드된 것이 보이는데 나머지는 deferred 라고 나옵니다.
이것은 WinDbg 의 lazy symbol loading (deferred symbol loading) 이라는 특징 때문에 그렇습니다.

WinDbg 는 심볼을 로드할 때 꼭 필요한 심볼만 올려놓고 나머지는 deferred 로 해놓고 심볼을 올리지 않습니다. deferred 로 된 녀석들은 나중에 해당 모듈이 WinDbg 상에서 실제 사용되는 순간이 발생해야만 로드가 됩니다. 필요한 것만 그때 그때 올려주는 나름대로 효율적인 방법입니다. ^^

WinDbg Help 에 보면 .reload 는 다양한 옵션을 가지고 있는데요.
제가 유용하게 사용하는 것만 몇가지 설명합니다.

.reload /i mydrv.sys (심볼이 맞지않아도 강제로 심볼 로드하기)

예를 들어 어제 빌드한 드라이버가 BSOD 를 발생시켜서 덤프가 만들어 졌는데 심볼은 보관하지 않아서 덤프분석을 할 수 없는 문제를 만났다고 가정합시다. 다행히도 어제 소스 코드를 그대로 보관하고 있었다고 하면 그것을 그대로 빌드하여 pdb 파일을 생성할 수 있습니다. 문제는 이 pdb 파일을 로드하려고 해도 WinDbg가 TimeStamp 등을 체크하여 symbol mismatch 에러를 내면서 심볼로드를 하지 않는다는 겁니다. 이런 경우에 심볼이 맞는지 확인하지 말고 강제로 올려달라는 /i 옵션을 사용하면 심볼이 올라갑니다.

.reload /f (심볼 모두 올리기)

보통 lazy symbol loading 상태로 그냥 사용하시면 되지만 혹시 모든 모듈의 심볼을 모두 올려 놓아야 할 경우가 있다면 /f 옵션을 사용해서 모든 모듈의 심볼을 올릴 수 있습니다.

.reload /u (심볼 모두 내리기)

반대로 모든 심볼을 모두 내려야 할 경우가 있다면 /u 옵션을 사용해서 모든 모듈의 심볼을 내릴 수 있습니다.

.reload /u mydrv.sys (특정모듈 심볼 내리기)

mydrv.pdb 를 로드하여 사용하고 있는데 새로 빌드한 mydrv.pdb 를 심볼패스에 복사하면 mydrv.pdb 가 사용중이라서 복사가 실패합니다. 이런 경우 /u mydrv.sys 옵션을 줘서 특정 모듈의 심볼만 내릴 수 있습니다.

.reload mydrv.sys (특정모듈 심볼 로드하기)

위와 같이 내려진 특정 모듈의 심볼만 다시 올리려면 mydrv.sys 처럼 모듈 이름을 줘서 로드합니다.


로드된 모듈 리스트 보기
 lm 명령을 이용하면 된다.

lm k : Kernel Mode 모듈 표시
lm u : User Mode 모듈 표시
lm m : 패턴을 검사하여 해당하는 것만 보여줌 <lm m my*>

lkd> lm
start    end        module name
00c80000 00c90000   NateOnHook40u   (export symbols)       C:\Program Files\NATEON\BIN\NateOnHook40u.dll
00cb0000 00cb9000   MgHookDll C (export symbols)       C:\Program Files\LG Software\On Screen Display\MgHookDll.dll
01000000 0106a000   windbg     (pdb symbols)          D:\Symbol\WebSymbol\windbg.pdb\D6EF677AA54441279479F0307F05A8941\windbg.pdb
016a0000 01784000   ext        (export symbols)       C:\Program Files\Debugging Tools for Windows\winext\ext.dll
01790000 017c1000   kext       (pdb symbols)          D:\Symbol\WebSymbol\kext.pdb\6B643FC4E9F94FF4ABA4CEF1FD6F89D61\kext.pdb


모듈의 심볼(Symbol) 검사
 x 모듈!패턴 을 입력하면 된다.

lkd> x nt!Ke*
804f8c02 nt!KeQuerySystemTime = <no type information>
804f8c9e nt!KeEnableInterrupts = <no type information>
80500e38 nt!KeSwitchKernelStack = <no type information>
804fad32 nt!KeReadStateProcess = <no type information>
804f9188 nt!KeReleaseInterruptSpinLock = <no type information>


데이터 타입(Date Type) 표시
 dt 데이터 타입 을 입력하면 된다.

lkd> dt _EPROCESS
   +0x000 Pcb              : _KPROCESS
   +0x06c ProcessLock      : _EX_PUSH_LOCK
   +0x070 CreateTime       : _LARGE_INTEGER
   +0x078 ExitTime         : _LARGE_INTEGER
   +0x080 RundownProtect   : _EX_RUNDOWN_REF
   +0x084 UniqueProcessId  : Ptr32 Void
   +0x088 ActiveProcessLinks : _LIST_ENTRY
   +0x090 QuotaUsage       : [3] Uint4B
   +0x09c QuotaPeak        : [3] Uint4B
   +0x0a8 CommitCharge     : Uint4B



메모리 덤프(Memory Dump)
 d* 명령들을 이용하면 된다.

db : Byte 형식 + Ascii 로 표시
dd : 데이터를 4Byte 형식으로 표시

lkd> db 8053db18
8053db18  8b ff 55 8b ec 8b 45 08-8b 4d 0c 8b 55 14 89 48  ..U...E..M..U..H
8053db28  0c 8b 4d 10 89 48 10 03-ca 89 48 14 8b 4d 18 83  ..M..H....H..M..
8053db38  c1 fe 89 48 18 8b 4d 1c-89 48 20 66 8b 4d 20 66  ...H..M..H f.M f



디스어셈블리(Disassembly)
 u 주소 를 이용하면 된다. 특정 함수를 디스어셈블리 하고 싶으면 uf 주소 를 하면 된다.

u 주소 : 주소에서 일부분만 디스어셈블리
u 주소1 주소2 : 주소1에서 주소 2까지 디스어셈블리

lkd> u 8053db18 or uf nt!NtOpenProcess
nt!KeInitializeProfile:
8053db18 8bff             mov     edi,edi
8053db1a 55               push    ebp
8053db1b 8bec             mov     ebp,esp
8053db1d 8b4508           mov     eax,[ebp+0x8]
8053db20 8b4d0c           mov     ecx,[ebp+0xc]


메모리 영역 속성 보기(VA Dump)
 !vadump 명령을 사용하면 된다. 만약 특정 메모리의 속성을 보고 싶다면 !vprot 주소 명령을 사용하면 된다.

0:000> !vadump
BaseAddress:       00000000
RegionSize:        00010000
State:             00010000  MEM_FREE
Protect:           00000001  PAGE_NOACCESS

BaseAddress:       00010000
RegionSize:        00001000
State:             00001000  MEM_COMMIT
Protect:           00000004  PAGE_READWRITE
Type:              00020000  MEM_PRIVATE


0:000> !vprot 30c191c
BaseAddress: 030c1000
AllocationBase: 030c0000
AllocationProtect: 00000080 PAGE_EXECUTE_WRITECOPY
RegionSize: 00011000
State: 00001000 MEM_COMMIT
Protect: 00000010 PAGE_EXECUTE
Type: 01000000 MEM_IMAGE


프로세스 관련
 모든 프로세스를 보기위해서는 !process 0 0 를 입력하면 된다. 디버거를 특정 프로세스에 붙이고 싶으면 .process /i [pid] 를 입력하면 된다.


lkd> !process 0 0
**** NT ACTIVE PROCESS DUMP ****
PROCESS 8a3a3490  SessionId: none  Cid: 0004    Peb: 00000000  ParentCid: 0000
    DirBase: 00780000  ObjectTable: e1001c70  HandleCount: 521.
    Image: System

PROCESS 8a184158  SessionId: none  Cid: 03f0    Peb: 7ffdd000  ParentCid: 0004
    DirBase: 17a40020  ObjectTable: e163dd70  HandleCount:  20.
    Image: smss.exe

PROCESS 89df4da0  SessionId: 0  Cid: 0440    Peb: 7ffd5000  ParentCid: 03f0
    DirBase: 17a40040  ObjectTable: e1c6cb18  HandleCount: 626.
    Image: csrss.exe


구조체 내용 보기

!strct _KMUTANT ff93a330

이렇게 명령을 주면 자료구조랑 값들이 같이 출력이 된다.


WinDBG 디버깅 과정 파일로 저장하기

Windbg를 이용해서 디버깅을 하다보면,

디버깅과정을 저장할 필요가 생깁니다.
또는 아래와 같은 상황이 있을수 있을겁니다.


- 다른분의 도움을 통해 디버깅한 내용을 참고하고 싶은경우
- 수십시간동안 켜놓은 결과를 저장해야하는경우. -> 화면 버퍼를 넘어가면 그동안의  내용이 사라지죠~
- .cls 를 습관적으로 사용하는경우.    -> 제경우입니다. T.T

이때 유용한 명령어가 바로.

.logxxx 계열 명령어입니다.


.logopen logfile
    >> 디버깅 과정을 저장할 로그파일 명을 지정합니다.
          ex) .logopen “c:\dbglog\logs.txt”

.logfile
    >> 현재 기록중인 디버깅 로그파일의 상태를 표시합니다.

.logclose
    >> 기록중이던 로그를 종료(완료)합니다.



유용하게 쓰세요~
(단, .logopen 이전의 내용은 저장되지 않습니다.` ^^)
참고하세요)
.logopen 정보 역시 Windbg WorkSpace 에 함께 저장됩니다.~ ^^


출처 : 다년간의 프로그래밍 경험 및 구글 search 결과

[출처] WinDBG 명령어 정리|작성자 갱주니

'scrap' 카테고리의 다른 글

명령어1  (0) 2010.03.18
명령어2  (0) 2010.03.18
명렁어4  (0) 2010.03.18
명령어5  (0) 2010.03.18
명령어6  (0) 2010.03.18

1.심볼(pdb), 소스 파일 설정하기

(WinDbg에서 심볼은 필요할 때 로드한다. 즉 지연해서 로드한다.)

ld [심볼이름] -> 강제로 심볼 로드하는 명령어

lm -> 현재 로드 되어있는 모듈 보여준다. 지연 되어 있으면 (deffered)라고 나온다.

.reload-> 심볼다시로드


2.| (process status)

3.~ (thread status)

4.변수 확인하기

.frame 1

dv(display variable)

5.dt r (typecast) (address)

(dt -r int 0x0012f5bc)

6.wt-> 모든 함수를 계층적으로 보여주는 명령어

7.브레이크 포인트

bp -> 주소를 이용해서 설정

bu -> 심볼이름을 이용해서 설정

(bu 060630_WinDbgTest!CWinDbgTestDlg::OnBnClickedButton1)

bl -> 브레이크 포인트 리스트

be (breakpoint enable), bd(breakpoint disable)

bc (breakpoint clear)

ba -> 메모리 액세스 브레이크 포인트

8.!critsec (임계섹션 주소), !locks(잠겨진 모든 임계섹션 주소 확인), !handle(프로세스내의 핸들 정보 표시)

'scrap' 카테고리의 다른 글

명령어2  (0) 2010.03.18
명령어3  (0) 2010.03.18
명령어5  (0) 2010.03.18
명령어6  (0) 2010.03.18
C++ Project Templete Create  (0) 2010.03.18

1)!vm 명령을 사용해서 현재 컴퓨터의 메모리 사용량을 살펴 보았습니다.


kd> !vm

*** Virtual Memory Usage ***
Physical Memory:   655234   ( 2620936 Kb)
Page File: \??\C:\pagefile.sys
   Current:   2095104Kb Free Space:   1999612Kb
   Minimum:   2095104Kb Maximum:      4190208Kb
Available Pages:   130442   (  521768 Kb)
ResAvail Pages:    577917   ( 2311668 Kb)
Modified Pages:       749   (    2996 Kb)
NonPagedPool Usage: 65522   (  262088 Kb)
NonPagedPool Max:   69378   (  277512 Kb)
********** Excessive NonPaged Pool Usage *****
PagedPool 0 Usage:   4025   (   16100 Kb)
PagedPool 1 Usage:    416   (    1664 Kb)
PagedPool 2 Usage:    414   (    1656 Kb)
PagedPool 3 Usage:    416   (    1664 Kb)
PagedPool 4 Usage:    411   (    1644 Kb)
PagedPool Usage:     5682   (   22728 Kb)
PagedPool Maximum:  86016   (  344064 Kb)
Shared Commit:        978   (    3912 Kb)


현재 !vm 명령을 통해서 NonPagedPool 메모리를 거의 다 사용한 것을 알 수 있습니다. 아마 특정 디바이스 드라이버 모듈에서 메모리를 많이 사용하는 것 같습니다.


2) !poolused 명령어를 사용해서 각각 메모리 할당 내용을 살펴 봅니다.

0: kd> !poolused
   Sorting by  Tag

  Pool Used:
            NonPaged            Paged
 Tag    Allocs     Used    Allocs     Used
 1394        1      520         0        0UNKNOWN pooltag '1394', please update pooltag.txt
 1MEM        1     3368         0        0UNKNOWN pooltag '1MEM', please update pooltag.txt
 2MEM        1     3944         0        0UNKNOWN pooltag '2MEM', please update pooltag.txt
 3MEM        3      248         0        0UNKNOWN pooltag '3MEM', please update pooltag.txt
 8042        4     3944         0        0PS/2 kb and mouse , Binary: i8042prt.sys
 AGP         1      344         2      384UNKNOWN pooltag 'AGP ', please update pooltag.txt
 AcdN        2     1072         0        0TDI AcdObjectInfoG 
 AcpA        3      192         1      504ACPI Pooltags , Binary: acpi.sys
 AcpB        0        0         4      576ACPI Pooltags , Binary: acpi.sys
 AcpD       40    13280         0        0ACPI Pooltags , Binary: acpi.sys
 AcpF        6      240         0        0ACPI Pooltags , Binary: acpi.sys
 AcpM        0        0         1      128ACPI Pooltags , Binary: acpi.sys
 AcpO        4      208         0        0ACPI Pooltags , Binary: acpi.sys

...

 WmiG       30     6960         0        0Allocation of WMIGUID 
 WmiR       63     4032         0        0Wmi Registration info blocks 
 Wmip      146     3504       182    18600Wmi General purpose allocation 
 Wmit        1     4096         7    49480Wmi Trace 
 Wrpa        2      720         0        0WAN_ADAPTER_TAG 
 Wrpc        1       72         0        0WAN_CONN_TAG 
 Wrpi        1      120         0        0WAN_INTERFACE_TAG 
 Wrps        2      128         0        0WAN_STRING_TAG 
 aEoP        1      672         0        0UNKNOWN pooltag 'aEoP', please update pooltag.txt
 fEoP        1       16         0        0UNKNOWN pooltag 'fEoP', please update pooltag.txt
 hSVD        0        0         1       40Shared Heap Tag , Binary: mrxdav.sys
 hibr        0        0         1    24576UNKNOWN pooltag 'hibr', please update pooltag.txt
 iEoP        1       24         0        0UNKNOWN pooltag 'iEoP', please update pooltag.txt
 idle        2      208         0        0Power Manager idle handler 
 jEoP        1       24         0        0UNKNOWN pooltag 'jEoP', please update pooltag.txt
 mEoP        1       88         0        0UNKNOWN pooltag 'mEoP', please update pooltag.txt
 ohci        1      136         0        01394 OHCI host controller driver 
 rx..       3     1248         0        0UNKNOWN pooltag '  rx', please update pooltag.txt
 sidg        2       48         0        0GDI spooler events 
 thdd        0        0         1    20480DirectDraw/3D handle manager table 
 SeSd      18    77056         2       96UNKNOWN pooltag 'SeSd', please update pooltag.txt
 vPrt        0        0        18    68160UNKNOWN pooltag 'vPrt', please update pooltag.txt
 TOTAL     3570214 209120008     38769 13066104

usbp 태그를 사용하는 모듈이 Nonpaged를 많이 사용하고 있습니다. 


3)!poolfind를 이용해서 특정 태그 메모리 사용내역을 확인해 봅니다.

kd> !poolfind SeSd 0

Scanning large pool allocation table for Tag: SeSd (827d1000 : 827e9000)

Searching NonPaged pool (823b1000 : 82800000) for Tag: SeSd

826fa130 size:   c0 previous size:   40  (Allocated) SeSd
82712000 size:   c0 previous size:    0  (Allocated) SeSd
82715940 size:   a0 previous size:   60  (Allocated) SeSd
8271da30 size:   c0 previous size:   10  (Allocated) SeSd
82721c00 size:   10 previous size:   30  (Free)      SeSd
8272b3f0 size:   60 previous size:   30  (Allocated) SeSd
8272d770 size:   60 previous size:   40  (Allocated) SeSd
8272d7d0 size:   a0 previous size:   60  (Allocated) SeSd
8272d960 size:   a0 previous size:   70  (Allocated) SeSd
82736f30 size:   a0 previous size:   10  (Allocated) SeSd
82763840 size:   a0 previous size:   10  (Allocated) SeSd
8278b730 size:  100 previous size:  290  (Allocated) SeSd
8278b830 size:   10 previous size:  100  (Free)      SeSd
82790130 size:   a0 previous size:   20  (Allocated) SeSd
82799180 size:   a0 previous size:   10  (Allocated) SeSd
827c00e0 size:   a0 previous size:   30  (Allocated) SeSd
827c8320 size:   a0 previous size:   60  (Allocated) SeSd
827ca180 size:   a0 previous size:   50  (Allocated) SeSd
827ec140 size:   a0 previous size:   10  (Allocated) SeSd

Searching NonPaged pool (fe7c3000 : ffbe0000) for Tag: SeSd

위 결과를 보니 메모리 할당(Allocated)된 만큼 해제(free)를 하지 않고 있는것 같습니다. 메모리 릭(memory leak)이 발생한것 같습니다.


4) Tag 이름으로 문제를 발생하고 있는 드라이버 찾기

WinDbg에서 태그로 이름으로 드라이버를 찾는 명령어를 제공하지 않는것으로 알고 있습니다.

그래서 저는 www.dumpanaysis.org 사이트에 나와있는 방법으로 찾습니다. 


직접 C:\windows\system32\drivers 드라이버 폴더에 찾는다. (cmd.exe)

C:\windows\system32\drivers>findstr /S /m /l hSeSd *.sys


출처 : 다년간의 프로그램밍 경험 및 http://www.dumpanalysis.org

'scrap' 카테고리의 다른 글

명령어3  (0) 2010.03.18
명렁어4  (0) 2010.03.18
명령어6  (0) 2010.03.18
C++ Project Templete Create  (0) 2010.03.18
LinkError 추적하기  (0) 2010.03.18

안녕하세요 신경준입니다. 어제는 날씨가 여름처럼 덥던데 오늘은 비가올려고 하는지 좀 서늘하네요. 일교차가 심한데 감기 걸리지 않게 조심하세요


 WinDbg에서 제가 생각할때 가장 많이 사용하는 명령어를 간단하게 정리했습니다.


[Debugger Setup : 심볼 설정]

 .sympath : 심볼 경로를 설정하는 명령어입니다.

 .sympath SRV*f:\localsymbols*http://msdl.microsoft.com/download/symbols


 .srcpath : source 경로를 설정하는 명령어 입니다. 

 .srcpath+ \\buildmachine\workspace\project\srt


 .lsrcpath : local 컴퓨터에 있는 source 경로를 설정하는 명령어 입니다.

 .lsrcpath+ c:\workspace\project\src 


 .lines : 디버깅 할때 소스 라인 정보를 보여주거나 보여주지 않게 설정한다.

 .lines -d (disable show source information)

 .lines -e (enable show source information)


 lm : 로드되어있는 모듈 정보를 알아본다.

s이름으로 시작하는 모듈의 정보를 알아낸다.

kd> lm m s*
start    end        module name
f9f73000 f9f7fd80   sysaudio     (deferred)                
fa04b000 fa09b400   srv          (deferred)                
faab7000 faac8500   sr           (deferred)                
facac000 facbae00   serial       (deferred)                
fb008000 fb00ba80   serenum      e:\mysymbols\SereEnum.pdb\.......
fb24f000 fb250000   swenum       (deferred)                

Unloaded modules:
f9f53000 f9f61000   swmidi.sys
fb0ae000 fb0b0000   splitter.sys
fb040000 fb043000   Sfloppy.SYS


!sym noisy 시끄러운 심볼을 로드한다.(이상한 심볼을 로드한다.)

!sym noisy Activates noisy symbol loading. 소란스러운 심볼을 로드하고 적용한다.

!sym quiet Deactivates noisy symbol loading. 소란스러운 심볼을 언로드하고 적용 해제한다.


 

.enable_unicode 1 : 디버깅 과정중에 unicode 스트링을 보여 줄수 있도록한다.

dt 명령어는 물론 Locals window and the Watch window. 에 있는 유니코드도 주소값 또는 hex 값이 아닌 스트링이 보여진다.


x 심볼을 조사해 본다.(Examine Symbols)

아래 명령어 예제는 prymes모듈에서 __n으로 시작하는 함수를 모두 보여주고 해당 심볼의 데이타 타입도 보여주라는 명령어이다.
0:001> x /t prymes!__n*
00427d84 char * myModule!__nullstring = 0x00425de8 "(null)"
0042a3c0 int myModule!_nstream = 512
Type information missing error for _nh_malloc
004021c1 struct MyStruct myModule!MyStructInstance = struct MyStruct
00427d14 <NoType> myModule!_NLG_Destination = <no type information>

'scrap' 카테고리의 다른 글

명렁어4  (0) 2010.03.18
명령어5  (0) 2010.03.18
C++ Project Templete Create  (0) 2010.03.18
LinkError 추적하기  (0) 2010.03.18
SVN 사이트  (0) 2010.03.18

"열혈강의 윈도우즈 시스템 프로그래밍"이란 책을 보면서 의문에 빠져 들었다. 

책 내용 중 내 눈에 들어온 한 문장이 있었는데

"인텔의 32비트, 64비트 CPU 뿐만 아니라, 근래에 임베디드 환경에서 사용되는 대부분의 CPU가 RISC 구조이다."

위의 문장이었다.


난 x86은 CISC 구조이고 ARM, MIPS 등등 많은 프로세서가 RISC 구조인데 어째서 저런 말이 나왔나 생각하게 되었다.

인터넷 검색 결과 아래와 같은 문장을 발견할 수 있었다.


사실상 CISC와 RISC의 구분은 모호하다. 다만, 이전의 아키텍쳐를 계속 발전시켜온 형태의 CPU, 즉 8086부터 발전해온 x86계열을 CISC, 비교적 최근에 개발된 CPU들을 RISC라 부르게 되는 경향이 있다. 현재 둘의 경계가 모호해진 이유는 최근의 CISC CPU들이 성능향상의 방안으로 RISC의 기술들을 채용했기 때문이다. 


위와 같다면 현재 아니 예전부터 CISC는 그 구조의 한계성 때문에 성능 향상을 꾀할 수 없게 되었고 RISC의 기술을 채용했다는 것이다.

RISC는 회로가 간단해 지고 성능이 좋아진다. 단점으로는 프로세서간에 차이가 많기 때문에 명령어가 달라서 프로그램을 공유해서 사용하기 어렵다는 것이다.

CISC의 장점은 범용성이 좋은 대신에 성능은 느리고 회로가 복잡해진다.

CISC는 성능 향상을 꾀하기 위해 슈퍼스칼라 구조를 도입하는 한편 RISC 기술을 채용했다. (슈퍼스칼라가 제대로 동작하려면 RISC 구조여야 한다.)

그래서 현재는 RCISC라는 괴상한 이름을 갖게 되었다.


예전에 선보였던 프레스캇은 엄청난 열을 발생하는 CPU였다. 오죽하면 "어머니 댁에 프레스캇 한대 놔드려야 겠어요". 이말이 나왔을까.

이때가 30단계 파이프라인을 갖는다고 했다. 현재 사용되는 'i7' 린필드의 파이프라인은 14단계라고 한다. 그 때문에 클럭은 줄었지만 성능은 예전보다 훨씬 뛰어나다. (게다가 소모 전력도 더 적다.)


결론은 CISC와 RISC는 각각 장단점을 갖고 있으며 우리가 가장 많이 사용하는 IA-32(IA-32는 x86으로 불린다.)은 RCISC이다. CISC의 길다란 명령을 잘게 잘라서 RISC 처럼 처리한다.


다른 페이지가 있는데 거기도 둘러 보도록

'Programming > 이것저것' 카테고리의 다른 글

Handshking  (0) 2010.03.19
Sliding Window  (0) 2010.03.19
CISC, RISC, CRISC(EPIC)  (0) 2010.03.18
펜티엄부터 린필드 i5까지, 인텔 어떻게 걸어왔나  (0) 2010.03.18
MTU  (0) 2010.03.18

CISC(Complex Instruction Set Computer; 복합명령형 컴퓨터)
RISC(Reduced Instruction Set Computer; 축소명령형 컴퓨터)
CRISC


   MPU는 동일 칩 위에 기억회로, 논리회로를 형성한 초소형 CPU(중앙연산처리장치)인데, 그 처리구조에 따라 CISC(Complex Instruction Set Computer; 복합명령형 컴퓨터)와 RISC(Reduced Instruction Set Computer; 축소명령형 컴퓨터)로 나뉜다.


     RISC(Reduced Instructions Set Computer)가 CISC(Complex Instructions Set Computer)보다 효율적으로 명령어를 처리한다. 386이나 486 컴퓨터의 중앙처리장치가 CISC방식이고, Power PC와 워크스테이션용 중앙처리장치가 대부분 RISC방식이다. 그러나 최근에는 CISC칩도 RISC구조의 일부를 채용하여 구분이 모호해지고 있다. 따라서 addressing mode는 적어야 하고, instruction format는 다양하지 못하다.


   PowerPC(Power Optimized with Enhanced RISC PC)는 RISC(Reduced Instruction Set Computer)방식의 CPU이며 이는 Intel이나 AMD사의 CISC(Complexed Instruction Set Computer)와는 전혀 새로운 방식의 것이다. PowerPC는 IBM과 Motorola, Apple사에 의해 공동 개발된 CPU로서 PPC601, 603, 603e, 604, 604e, 740, 750(G3), 7400(G4) 순서로 발전하게 된다. RISC를 우리말로 축약형 컴퓨터라고 표현한다. 대부분의 CPU들이 방대한 명령어를 가지고 있음에도 실제로 자주 사용하는 명령어는 전체 명령어의 10%도 미치지 못함에 착안하여 명령어의 갯수를 줄이고, 그 대신 CPU 인사이드 캐시, 분기 예측 기능, 수퍼스케일러, 비순차 명령 실행, 파이프라이닝, 레지스터 개수 증가등의 본질적인 CPU 성능 개선 방안을 적용한 것이다. RISC기술은 Intel의 x86계열을 제외한 모든 CPU들, 즉 SUN의 Sparc나 DEC의 Alpha, MIPS의 R계열에 현재 채택되어 있다.


   사실상 CISC와 RISC의 구분은 모호하다. 다만, 이전의 아키텍쳐를 계속 발전시켜온 형태의 CPU, 즉 8086부터 발전해온 x86계열을 CISC, 비교적 최근에 개발된 CPU들을 RISC라 부르게 되는 경향이 있다. 현재 둘의 경계가 모호해진 이유는 최근의 CISC CPU들이 성능향상의 방안으로 RISC의 기술들을 채용했기 때문이다. 그러나 현재의 x86의 경우 오래된 아키텍쳐를 계속 발전시켜 왔기 때문에, 칩에 내장된 트랜지스터의 개수가 순수 RISC칩의 수배에 이르게 되었다. iMac에 사용되는 G3(PPC-750)의 경우 펜티엄 II의 절반에도 이르지 않는 트랜지스터의 조합으로도 더 나은 성능을 나타낸다. 최근에 개발된 G4(PPC-7400)은 펜티엄 III의 2/3의 clock만 으로도 3배이상의 성능을 보여준다. 이는 아키텍쳐가 MHz보다 더 중요하다는 것을 보여주는 단서이기도 하다.


1. CISC(Complex Instruction Set Computer)

CPU의 동작을 지시할 때 한번에 여러가지 일을 하도록 지시할 수 있는 명령어 체계를 갖는다. CPU안의 내부 명령어가 100개 이상을 사용하는 프로세서를 CISC라고 한다. 내부 명령어가 많기 때문에 기능마다 하나의 명령어를 주기 때문에 좋을 것 같이 보이지만 실제로 프로그래밍을 하기 어렵고 많은 명령어로 수행 시간이 길어질 경우가 많다. 일반적으로 사용되는 IBM 컴퓨터의 XT에서 486 CPU와 매킨토시에서 사용하는 680x0 CPU는 CISC 개념이 사용된 프로세서이다.

CISC는 인텔 ‘i80486’ ‘펜티엄’ 등의 MPU에 널리 채용되고 있는 CPU이다. CISC는 하나의 명령으로 복잡한 처리가 가능하지만 회로설계가 복잡해지는 경향이 있다.
최근 동작 주파수가 해마다 향상되어 현재는 335MHz에 달하고 있어 RISC와의 격차를 줄여 가고 있다


2. RISC(Reduced Instruction Set Computer)

CPU의 동작을 지시할 때 한번에 하나의 일만을 하도록 지시할 수 있는 명령어 체계를 갖는다. CPU안의 내부 명령어를 최소로 줄여서 수행 시간을 단축하는 것으로 단순화한 명령어를 조합해서 다른 필요한 명령어를 만드는 형태이다. 일반적으로 CISC보다 50%에서 75% 정도 더 빠르고 워크스테이션과 같은 중형 컴퓨터에 사용되는 CPU에 사용되고 있다. 모토롤라 사의 R4000은 RISC명령어 체계를 가지고 있다


최첨단 서버 워크스테이션 ‘모델 250’을 실현하는 CPU는 RISC형 CPU를 채용하고 있다. 또 인텔의 ‘펜티엄’에 대항하는 ‘파워PC’ 등도 RISC형으로 되어 있다. RISC는 종래의 CISC에서 복잡하고 종류도 많았던 명령을 정리하고 단순화하여 고속화 보드형 프로세서로 컴파일러에 의한 명령렬(列)의 최적화에 의해 고속화를 실현한다. CISC에 비해 구조가 간단하고 주파수를 높이는 일이 쉬운 것이 그 특징이다.


나아가 이 RISC를 여러 개로 병렬화하여 성능 향상을 꾀해 범용 대형 컴퓨터에 접근하고 있는 것이 최근의 서버 워크스테이션의 특징이다. <표 2>에 RISC의 상용화 예(NEC)를 나타냈다. 또 


(1) RISC, CISC,CRISC

    RISC는 정확히 말하면 `축약된 명령어 표를 이용한 정보처리방식'이다. 여기에 대비되는 것이 `복합 명령어 표를 이용한 정보처리방식' 곧 CISC이다. 386이나 486 컴퓨터의 중앙처리장치가 CISC방식이고 Power 개인용 컴퓨터와 워크스테이션용 중앙처리장치가 대부분 RISC방식이다. 펜티엄은 두 가지를 적당히 섞어 쓴다. 컴퓨터중앙처리장치는 명령어사전에서 원하는 명령어를 찾아내, 실행 시 키는 작은 반도체라고 생각하면 이 기술을 이해하기 쉽다. 물론 중앙처리장치 나름의 명령어이고, `dir'(파일목록보기) 같은 도스 명령어와는 전혀 다른 것이다. RISC방식 칩의 명령어들은 길이가 짧고 크기가 같다. 또 한 명령어는 한 가지 기능만 한다. 길이가 같아 찾기가 쉽고 기능이 한 가지밖에 없어 동시에 따로따로 처리한 뒤 결과를 합칠 수 있다. 계산기를 10개쯤 놓고 동시에 계산을 해서 합산하면 결과가 나오는 식이다. 이 때문에 명령어 처리시간이 많이 줄어든다. RISC의 장점은 CISC방식을 보면 더욱 뚜렷해진다. CISC는 명령어들의 크기가 제각각이며, 이 명령어들을 같은 크기로 잘게 잘라 처리한다 . 한 명령어를 자르니 앞뒤 순서가 생기고, 따라서 동시에 처리하지 못한다. 그렇지 않으면 뒤죽박죽이 되기 때문이다.  이런 단점 때문에 CISC방식은 인기가 떨어지고 있다. 486급 중앙처리장치의 후속제품이기 때문에 CISC방식에 바탕을 둔 펜티엄칩은 대신 잘게 자른 명령어를 동시에 처리하는 기술을 RISC방식에서 빌려왔다. 그래서 RISC와 CISC를 혼합한 CRISC방식이라고 부른다.


(2) RISC와 CISC 그 차이에 대해서

    RISC와 CISC는 CPU의 아키텍쳐,즉 구조적 측면의 차이로, 어떤 일정한 방법으로 명령어를 처리하느냐에 따라 구분된다. 예전에는 RISC를 단순히 CISC를 간소화 시킨 정도로 보는 시각도 있었지만 현재에 와서는 그런 개념을 뛰어넘고 있다. 일단 현재 우리가 대부분 쓰고 있는 CISC CPU에 대해서 설명을 해보자면 일단 CISC의 어원부터 짚고 넘어가야 할 것 같다. CISC는 Complex Instruction Set Computing의 줄인 말로, 소위 복합 명령 집합 계산,컴퓨팅으로 말 그대로 복합적인 명령어를 가지고 있다. 일단 컴퓨터에 어셈블리, 또는 베이직 따위의 언어로 명령을 주면, CPU에서 그것을 여러 단계로 세분화되어 마이크로 코드(Microcode)라 하는 수행 절차를 걸쳐 처리하게 된다. 그런데, 이런 수행에 있어 좀 더 복잡한 연산에 대응하는 명령어 셋을 추가하는 것이 CISC로, 여러 개의 단순한 명령어 셋으로 명령을 처리하기 보다는 그것들을 포괄하는 연산 셋으로 한 개의 명령어로 처리해 효율을 도모한다는 것이 CISC다. MMX도 이런 의미에서 볼 때는 CISC의 확장이라 볼 수 있겠다.


  한편, RISC는 CISC와는 반대로 기본 명령어 셋을 추구하는 형태이다. 그러나 RISC라고 해서 단순히 명령어를 간소화 시킨 형태라고 봐서는 안된다. 단순히 명령어만 간소화 시킨다면, CISC보다 뛰어날 이유가 없기 때문이다. RISC에서는 컴퓨터에서 주 수행되는 작업을 색출해, 거기에 최적화 시켜 만든다. 그러니까 핵심이 되는 작업 항목에 특화시켜 전체적인 속도를 향상시키는 것이다. 한가지 예를 들어 설명하자면, 모든 컴퓨터 작업에 있어서 읽고,쓰는 작업은 항상 포함된다. 일단 데이터를 읽어 들이고 쓰는 과정은 로딩과 스왑으로 항상 생기기 때문이다. 그 과정에 최적화시키면 그 만큼 작업 속도,즉 전체적인 처리 효과를 얻게 되는 것이다. 그러기 위해선 다른 명령어 셋과는 달리 다른 공정이 필요한데, 요즘에 와선 CISC도 이런 공정을 채용해 단일 사이클에 처리하는 명령어를 많이 갖게되었다.

요즘에 와선 이런 점을 통해서 RISC와 CISC의 차이를 구분할 수 없게 되었고, 캐시에 따른 차이가 두각을 드러냈다. 바로 CISC가 가진 맹목으로, 복합적인 명령어를 많이 가지려고 하다 보니, 트랜지스터 직접도가 과다하게 늘어나는 것이다. CISC가 가진 비효율이라 할 수 있겠다. RISC에서는 이와는 달리 명령어 체계 단순화를 지향하고, 핵심명령 특화 체제에 있어, 트랜지스터 집적에 여분이 있기 때문에 L1 캐시를 증대시켜 성능을 더욱 증대 시키는 것이다. 펜티엄 프로의 경우 L1 캐시 16KB(명령어/데이터 캐시 합친 양)이고 L2 캐시를 제외한 펜티엄 프로의 트랜지스터 집적 수가 550만개인데 반해, RISC CPU인 Power PC 604e 프로세서의 경우 L1 캐시가 64KB인데도 트랜지스터는 510만개다.

특히, 604 프로세서의 세부적인 RISC의 특성을 살펴보자면 한 실행주기당 여러 명령을 동시에 처리하는 슈퍼스칼라(6~7개의 명령어를 처리한다.)를 구현하고 있다. 이상의 서술한 점이 RISC가 CISC를 앞서는 대략적인 이유와 구조적 특징이다. R10000 프로세서 같은 워크스테이션 RISC 프로세서에 대한 언급도 하고 싶지만 그러기엔 본 필자의 역량이 너무나도 떨어지는 듯하다. 다만 O2에 사용된 R10000 프로세서를 기반해 잠깐 설명하고자 한다. R10000 프로세서의 경우 clock은 그리 높지 않다. 175MHz의 동작 clock을 가진 제품도 있기 때문이다. 1MB의 L2 캐시를 가지고 있으며,(R5000SC의 경우 5MB의 L2 캐시를 탑재하고 있다.) R10000 프로세서는 RISC프로세서의 정점을 보여주는 CPU로 RISC의 효율성을 최대한으로 발휘하고 있다. 4방향 슈퍼스칼라(4개의 명령 동시 처리)에 64비트 구조를 가지고 있으며 비순차적 명령 실행 방법과 128비트 L2 캐시 버스에 별도 5개의 실행 유닛을 가지고 있다. (PC 계열의 난폭한 마케팅을 하면 R10000 프로세서는 128비트 프로세서란 말을 들을 수도 있다는 얘기가 된다.)


   CISC는 RISC를 clock 속도로써는 충분히 능가할 수 있다. 다만 그 과정에서 트랜지스터 집적도가 너무 과다하게 올라가고 있다. 특히 Intel은 CISC에 MMX를 덧붙여 CISC에 CISC를 더한 셈이 되었다. 어차피 MMX의 세부를 열어보면 그것 역시 CISC의 확장이 되는 셈이기 때문이다. 특정 연산에 대한 명령어를 추가하는 것이 결국 CISC의 특성이 아니던가. Intel이 트랜지스터 집적도를 무리하게 올리면서 지금의 가격을 형성하고 인하 정책을 펼치는 것이 신기할 정도다. 아마도 현재의 PC CPU는 RISC로 갈 가능성은 희박할 듯 하다.

그 예로 Intel이 내세우는 차세대 CPU 머시드는 EPIC라고 하는 CISC를 또 다시 확장한 형태로 구현된다고 하니 말이다.( 그 결과 머시드의 트랜지스터 집적수는 3억개라는 천문학적인 숫자에 이르고 말았다...--;) CISC와 RISC, 이 둘은 다 각기 장단점이 있다. CISC는 복합 명령을 가짐으로써 하위 호환성을 충분히 확보할 수 있고 RISC의 경우 효율적인 CPU 구조를 가지고 있다. 다만 CISC는 트랜지스터 집적에 있어서 효율성이 결여되어 있고, 그 결과 성능 향상에 난점을 겪고, RISC의 경우 하위 호환을 위해 에뮬레이션 방식을 채택해야 하고, 일정한 환경에서만 성능을 발할 수 있는 단점이 있는 것이다. 따라서 호환성이 절대적으로 필요한 PC 환경에서는 CISC가, 전문적인 일에 있어서는 RISC가 서로 독보적인 우위에 점하고 있는 것이다.

'Programming > 이것저것' 카테고리의 다른 글

Sliding Window  (0) 2010.03.19
CISC & RISC  (0) 2010.03.18
펜티엄부터 린필드 i5까지, 인텔 어떻게 걸어왔나  (0) 2010.03.18
MTU  (0) 2010.03.18
ICMP  (0) 2010.03.18

PC의 역사가 사반세기를 넘은 지 오래지만 PC의 진화는 아직 ‘현재 진행형’이다. 처음 PC가 선보일 때만 해도 이 기계는 사무실의

업무용 컴퓨터 그 이상의 가치를 갖지 못했지만 어느새 PC는 가정의 공부방과 거실로 넘어왔다. 흑백 화면의 아스키 이미지를 조합한

조잡한 게임은 영화 수준과 비교해도 그리 흠잡기 어려울 정도의 풀 HD 수준까지 발전했고, 사무 작업 위주의 용도 역시 이제는 영화,

음악, 게임 등 엔터테인먼트 기능이 기술 발전의 큰 흐름을 만들고 있다.



CPU 역시 그러한 큰 흐름에 맞춰 끊임 없이 발전해왔다. 인텔이 ‘HD급 영상과 게임’을 내세워 코어 아키텍처 CPU를 내놓은지 3년.

그 사이에 세상은 단순 HD를 넘어 풀 HD, 그리고 그 이상의 세상을 노리고 있다. 이런 세상의 변화에 인텔은 어떤 대답을 내놓을까?

이 질문에 대해 인텔은 ‘네할렘 아키텍처’라는 새로운 기술을 해답으로서 내놓았다.


이미 2008년 말에 그 모습을 선보인 네할렘 아키텍처는 워크스테이션과 서버 시장에서 그 가치를 검증받았고, 이제 개인용 PC로

그 영역을 넓힌다. 그것이 코어 i5와 i7, 일명 ‘린필드(Lynnfiled)’ CPU다.


코어 i5의 뿌리는 펜티엄 프로

CPU의 성능을 높이는 방법 가운데 가장 쉽게 생각할 수 있는 것은 작동 속도를 높이는 것이지만, 성능이 획기적으로 좋아지지는

않는다. 더구나 속도를 무한정 끌어 올릴 수 있을 것이라는 믿음의 뿌리인 ‘무어의 법칙’만으로는 한계가 있다는 것을 지난 몇 년동안

인텔을 비롯한 반도체 기업들은 몸소 느끼게 되면서 ‘속도 만능 주의’는 더 이상 고개를 들 수 없게 되었다. 속도를 높일 수 없다면

반도체 기술의 기본 뿌리, 아키텍처(Architecture)를 바꿀 수 밖에 없다.



지난 몇 년동안 인텔은 무작정 빠른 속도에 대한 욕망을 살짝 접고 아키텍처의 개혁을 꾸준히 이어가며 새로운 CPU를 내놓았다.

‘린필드’ CPU 역시 그러한 아키텍처 개혁의 가장 최신판이다. 코어 i5와 i7의 진정한 장점을 이해하기 위해 인텔이 지금까지 어떤

생각으로 아키텍처 개혁을 이뤄왔는지 먼저 살펴봤다.


무어의 법칙 황금기, 그리고 멀티미디어 명령의 시대

린필드 코어 CPU를 비롯한 지금 팔리고 있는 대부분의 인텔 CPU들은 펜티엄 프로 시절에 처음 선보인 ‘P6’ 아키텍처에서 선보인

기술을 맨 밑의 뿌리로서 삼고 있다. 90년대 중반 등장한 펜티엄 프로는 가정용이 아닌 사무 및 전문가 전용 CPU로서 그리 많이

팔리지는 않았지만, 린필드 CPU의 증조 할머니로 불릴만한 여러 기술을 담았다.


아톰을 뺀 거의 모든 인텔 x86 CPU가 쓰는 ‘아웃오브오더(Out-of-Order)’ 명령 실행 구조를 처음 쓴 것은 펜티엄 프로이며,

32비트 환경에서 4GB 또는 그 이상의 메모리를 쓸 수 있도록 하는 변형 메모리 관리 기법인 36비트 PAE(Physical Address

Extension, 물리 메모리 확장) 역시 펜티엄 프로에서 처음 선보인 것이다. 아웃오브오더 실행 구조는 CPU가 다음 자료를 기다리며

노는 시간을 줄여 같은 작동 속도에서 성능을 크게 높여 PC 역사에 큰 획을 그었으며, CPU에 2차 캐시 메모리를 넣은 것 역시

데스크탑 PC용 x86 CPU 가운데는 펜티엄 프로가 첫 번째 테이프를 끊었다. 어찌 보면 지금 나와있는 최신 CPU의 주요 기술은

이 펜티엄 프로에 뿌리를 두고 있다 해도 좋을 것이다.



그 뒤를 잇는 펜티엄 II와 펜티엄 III는 펜티엄 프로를 바탕으로 이것을 가정용 PC에 맞게 업그레이드했다.

P6 아키텍처를 그대로 유지하면서 펜티엄 MMX CPU에 처음 선보인 ‘MMX(MultiMedia eXtension)’ 기술을 더했는데, MMX는

이미지/영상 편집과 동영상 재생, 게임 등 멀티미디어 작업에서 자주 쓰는 작업을 간단한 명령 한 번으로 실행하도록 하여 효율성을

높인 x86 CPU 최초의 SIMD(Single Instruction, Multi Data, 단일 명령 다중 데이터 처리) 기술이었다.


펜티엄 III 역시 이러한 흐름은 변함이 없는데, 공정 기술을 높여 작동 속도를 더욱 끌어 올리고, MMX의 뒤를 잇는 2세대 SIMD 명령,

SSE를 새롭게 내놓았다. 아키텍처의 큰 변화는 없지만 공정 기술을 꾸준히 끌어 올린 결과 펜티엄 III 시대에는 작동 속도가 1GHz를

넘어 최고 1.4GHz에 이르기도 했다.



펜티엄 프로부터 펜티엄 III 시절의 아키텍처 특징은 무너질 기색을 보이지 않던 무어의 법칙에 따라서 공정 기술을 차근차근 끌어

올리며 작동 속도를 높여 기본 성능을 끌어 올리고, 점차 그 비중이 커지던 영화 및 이미지 처리, 게임에 맞춰 이러한 작업의 효율성을

높이는 SIMD 기술을 받아들인 점이다. 이미 아키텍처의 큰 진화는 펜티엄 프로에서 이뤄 냈으며, 그 이후에 나온 CPU는 이 아키텍처

를 잘 다듬고 뛰어난 공정 기술의 혜택인 빠른 작동 속도를 이끌어내 사용자들의 마음을 사로 잡았다.


끊임없는 질주 펜티엄 4와 그 불편함

펜티엄 프로부터 시작된 P6 아키텍처는 세 세대를 걸쳐 그 역할을 충분히 해냈지만 인텔도 새로운 아키텍처를 고민해야만 했고,

그 결과물인 2000년에 새롭게 선보인 펜티엄 4는 P6의 마이너 업그레이드가 아닌 완전히 새로운 아키텍처, ‘넷버스트(Netbust)’

를 처음 선보인 CPU가 되었다.


넷버스트 아키텍처의 특징을 한 마디로 정리하면 ‘작동 속도를 더욱 빠르게’ 만드는 것이다.

파이프라인의 단계가 많아지면 많아질수록 같은 공정 기술을 써도 작동 속도를 높일 수 있는데, 펜티엄 4는 처음에는 20단계,

나중에는 31단계까지 파이프라인 단계를 늘렸다. 기껏해야 10개 수준인 펜티엄 III보다 훨신 많은 단계를 거쳐 명령 실행이

이뤄지게 되는데, 이렇게 파이프라인의 단계가 늘면 작동 속도는 빨라지지만, 만일 잘못 실행한 명령이나 데이터가 있으면 그

작업을 취소하고 처음부터 최고 31단계의 처리 과정을 다시 밟아야 하기에 클럭 당 실행 명령 수(IPC)가 떨어지는 문제가 생긴다.



인텔은 처리를 잘못 하는 실수를 줄여주도록 분기 예측(Branch Prediction) 효율성을 높였고, 새로운 분기 예측 기술과 더 빨라진

작동 속도를 더하면 넷버스트 아키텍처 CPU가 P6 아키텍처 모델보다 더 좋은 성능을 낼 것으로 예상했다. 여기에 CPU와 칩셋을 잇는

시스템 버스 속도를 종전의 최고 3배 수준으로 높이고 넷버스트 아키텍처에 맞춘 SSE2 기술을 더해 더욱 성능을 끌어 올렸다.


1.4GHz를 첫 모델로서 출발한 펜티엄 4는 공정 기술을 한번 더 바꾼 노스우드 코어 모델까지 큰 무리 없이 인텔의 생각대로 빠르게

속도를 끌어 올렸다. 그 사이 시스템 버스 속도는 더 빨라지고 2차 캐시 메모리 용량은 더 커졌으며 CPU 코어 하나로 두 개의

스레드(Thread)를 처리할 수 있는 가상 듀얼 CPU 기술, ‘하이퍼스레딩’이 첫 선을 보였다.

이러한 변화는 펜티엄 4의 성능을 사람들이 납득할 수 있는 수준 이상으로 높이는 데 큰 역할을 했다.


그렇지만 펜티엄 4를 내놓을 때의 생각은 몇 년만에 벽에 부딪혔는데, 더 이상 무어의 법칙이 듣지 않게 된 것이다.

무어의 법칙은 18개월마다 반도체의 속도는 두 배 빨라진다는 것인데,  130nm 공정 기술까지는 무어의 법칙을 뒷받침하기에 별

어려움이 없었지만, 90nm 공정부터는 이론에 훨씬 미치지 못하는 결과를 낳았다. 전력 소비량과 반도체 크기는 생각만큼 줄지

않았고, 이 때문에 작동 속도를 높이는 데 어려움을 겪었다.



바로 3세대 펜티엄 4 코드명 ‘프레스콧’이 그 주인공이다. 최고 4GHz에 가까운 작동 속도를 내는 데 성공했지만, 실질적으로 CPU의

성능 증가 속도는 눈에 띄게 줄어들었고, 그에 비해 발열과 전력 소모량은 엄청나게 늘었다. 때마침 불어닥친 전 세계적인 에너지

절약 열풍은 속도 만능 주의를 버리고 CPU 아키텍처를 ‘효율성’ 위주로 바꾸게 만드는 힘이 되었다.

결국 인텔은 65nm 공정 펜티엄 4 계획(일명 테자스)을 버리고 조금씩 개발을 하던 새로운 아키텍처를 빠르게 현실로 옮기는 결정을

내렸다. 바로 ‘코어 아키텍처’다.


코어 아키텍처로 연 에너지 중심의 르네상스 시대

코어 아키텍처는 펜티엄 4 시절에 나온 노트북 PC용 CPU, 펜티엄 M에서 쓰던 ‘배니어스 아키텍처’에 뿌리를 둔다.

펜티엄 M은 펜티엄 III가 쓰던 P6 아키텍처를 뿌리고 펜티엄 4의 장점인 빠른 시스템 버스와 멀티미디어 기술을 더했는데,

작동 속도는 펜티엄 4에 한참 미치지 못했지만 성능은 펜티엄 4에 그리 뒤지지 않고 전력 소비량도 적어 인기가 많았다.



2006년 코어2 듀오의 발표와 함께 첫 선을 보인 코어 아키텍처는 P6 아키텍처를 그 어머니로서 삼고 있지만 여기에 넷버스트의

장점을 더해 더 좋은 방향으로 이끌어냈다. P6 시절보다 조금 늘어난 14 단계 수준으로 줄인 파이프라인 단계는 CPU 작동 속도를

2GHz 이하로 끌어 내렸지만, 전력 소비량을 줄이고 실제 성능을 두 배 가까이 작동 속도가 빠른 빠른 펜티엄 4 수준까지 끌어 올렸다.


여기에는 명령 처리의 효율성을 높인 Micro-Ops 설계와 프레스콧 코어 펜티엄 4 CPU에서 선보인 SSE3 멀티미디어 기술, 넉넉한

2차 캐시 메모리, 그리고 펜티엄 4에서 가져온 고속 쿼드 펌프 시스템 버스의 역할이 컸다. P6 아키텍처에 없던 이러한 추가 기술은

코어 아키텍처를 ‘P6 아키텍처의 재탕’이 아닌 ‘P6와 넷버스트 아키텍처 모두의 공식 후계자’로서 인정할 만큼 좋은 성능을 보여

주었다. 1.86GHz 속도를 갖는 코어2 듀오가 2.8GHz 속도를 내는 펜티엄 4 또는 펜티엄 D보다 성능이 좋을 정도로 코어 아키텍처의

모험은 성공을 거두었다.



또한 펜티엄 D CPU에서 처음 선보였고 코어2 듀오에서 널리 쓰인 듀얼코어 기술은 코어 하나의 성능에 목을 매달던 과거의 CPU와

다른 ‘멀티 코어(Multi-Core)’로 눈을 돌리는 계기가 된다. CPU를 두 개 또는 그 이상 병렬로서 연결하는 SMP(대칭형 멀티 프로세서)

는 비록 절대 작동 속도는 빨라지지 않지만 한 번에 많은 작업/스레드를 처리할 수 있어 많은 작업을 동시에 하거나 멀티 스레드 설계를

한 작업을 하면 CPU 하나를 쓸 때보다 성능이 좋아진다.


작동 속도를 높이는 데 집착하던 P6나 넷버스트 아키텍처와 달리 과거의 아키텍처의 장점만을 살린 기본 구조와 멀티코어 기술을

바탕으로 한 코어 아키텍처 CPU는 철저히 ‘에너지 효율성’을 따졌다. 코어2 듀오 CPU는 열 설계 전력(TDP)는 65W 수준에 불과

하지만 과거의 130W를 넘나드는 수준의 펜티엄 D CPU 이상의 성능을 냈으며, 줄어든 발열은 쿨러의 소음까지 줄여 ‘조용하고

유지비 부담이 적은 CPU’라는 좋은 기억을 남겼다.

이런 인텔의 노력과 경험들을 녹인 최신 프로세서가 바로 코어 i5, i7로 이름 붙여진 린필드 프로세서다.

'Programming > 이것저것' 카테고리의 다른 글

CISC & RISC  (0) 2010.03.18
CISC, RISC, CRISC(EPIC)  (0) 2010.03.18
MTU  (0) 2010.03.18
ICMP  (0) 2010.03.18
TCP/IP PPT 에서 뜯어왔음ㅋ  (0) 2010.03.18

출처 : http://www.htsns.com


질문1
 NDIS.sys란 계층이 있는데요
 저는 NDIS가 미니포트 IM 프로토콜 드라이버를 감싸고 있는
 그림만 봐서 이그림은 좀 생소하네요
 이그림의 의미가 미니포트에서는 어퍼에지쪽으로 NDIS인터페이스에 맞춰주고 프로토콜 드라이버에서는 로워에지쪽으로 NDIS의 인터페이스에 맞춰준다는 의미인가요?

 네 감싸고 있는 것이 맞습니다. 실제 코드 구현으로 하면, ndis.sys는 하나의 라이브러리라고 생각하시면 됩니다. 즉 표준 인터페이스를 제공함으로써 미니포트 드라이버와 프로토콜 드라이버를 분리시켜서 서로 다른 업체에서 개발할 수 있도록 합니다. 즉 Lower, Upper Edge 함수들은 콜백함수들입니다. 이 부분은 open block이라는 개념으로 미니포트와 프로토콜을 서로 연결 시켜서 미니포트에서는 Lower-Edge 함수들을 ndis 함수들을 통해 호출할 수 있도록 하고 Upper-Edge 함수들도 마찬가지입니다.
 즉 NdisSend 함수를 호출하면 내부적으로 초기화 시에 등록한 미니포트의 Upper-Edge 함수를 호출하게 합니다. 즉 MiniportSend함수를 호출합니다. 이런 구조가 ndis 라는 아키텍처입니다. 

질문2
 그럼 IM드라이버가 들어간다면 그림에서 어떤식으로 연결이 되는건가요?
 
 
프로토콜, 미니포트 드라이버 구조를 이해하고 계시면 im도 이해하는데 큰 어려움은 없을 겁니다. 즉 프로토콜과 연결하는 부분은 im의 미니포트에 해당하고 미니포트와 연결하는 부분은 im의 프로토콜의 해당합니다. 그리고 im 내에서 미니포트와 프로토콜 부분은 내부 바인딩 개념으로 ndis 가 알아서 처리를 해주고 잇습니다. 과거 im 인터페이스가 제공을 하지 않는 ndis 버전에서는 im 드라이버와 같은 역할을 하는 드라이버를 개발할 때, 직접 ndis protocol 드라이버와 가상 nic 드라이버를 만들어서 내부적으로 직접 연결을 시켜서 필터 드라이버를 개발했습니다.

 다시 함수 정리를 한다면, tcpip.sys라는 ndis protocol드라이버와 virtual nic driver와 바인딩 시키고 자체 ndis protocol 드라이버를 개발 미니포트 드라이버와 바인딩 시킵니다. tcpip.sys에서 ndissend함수를 호출하면 virtual nic driver와 바인딩 되었기 때문에 MiniportSend 함수가 호출될 겁니다. 그럼 MiniportSend 함수에서 자체 ndis protocol에서 ndisopenadapter함수를 통해 얻은 바인딩 핸들을 가지고 ndissend 함수를 호출하면 미니포트의 MiniportSend 함수가 호출되는 구조로 개발이 되었습니다. IM 드라이버인 경우 이런 컨텍스트 관리가 ndis 아키텍처에서 관리가 되는데 자체 위 구조로 개발하게 되면 자체적으로 연결 컨텍스트 관리를 해줘야 되는 불편함이 있습니다.

질문3
 그림에서 1번을 보면 TDI 트랜스포트와 프로토콜이 TCPIP.sys란
 파일로 묶여있는데요.. 두개가 원래 공존하는겁니까?
 
 
네 공존합니다.
즉 프로토콜 드라이버를 개발할 때 소켓단하고 연결을 하려면 tdi transport 계층이 필요합니다.

질문4
 그렇다면 DDK샘플에서 프로토콜드라이버 샘플도 TDI트랜스포트와 프로토콜드라이버로 이루어져 있는겁니까?
 
 
packet이나 ndisuio는 소켓 단과 연결을 하지 않습니다. 그래서 tdi transport 계층이 없습니다. 자체 프로토콜 드라이버기 때문에 바로 어플리케이션과 연결해서 패킷 송/수신을 할 수 있는 하나의 패킷 드라이버라고 할 수 있습니다.

질문5
 우리가 프로토콜 드라이버를 개발하면 기존에 있는 TCPIP.sys를 대체하게 되는겁니까?

 아님 아래쪽이나 위쪽으로 삽입이 되는겁니까?
 
 
병렬 구조입니다. 새로운 프로토콜 드라이버가 생기는 겁니다. 즉 tcpip.sys와는 독립적입니다.

질문6
 그림에서 2번의 TDI.sys는 NDIS.sys처럼 라이브러리(?)를 나타내는겁니까?
 
질문7
 그림 1에서 TDI Transport는 왜 Transport라는 이름이 붙은건가요?
 그림3에서 TDI Client는 왜? Client라는 이름이 붙은건가요?
 Afd.sys에서 Afd는 무슨 약자인가요?
 
 
음 의미상 그런 구조이기 때문에 그런 이름을 붙인것 같습니다. 제 생각입니다만,

transport라는 이름은 osi 7계층에서 전송 계층에 해당하는 부분이라 이런 이름을 사용하지 않았나 생각이 들고 client라는 것은 transport 서비스를 이용하는 부분이기 때문에 client라는 이름을 사용한 것 같습니다.

afd는 모르겠습니다. 추정하는 것은 address family driver 약자가 아닐까.... 생각이 듭니다. 소켓에서 AF_NET이라는 소켓 이름이 사용하는데 AF Address Family 약자라서 ...

질문8
그림3 TDI Client에서요 아래쪽은 TDI인터페이스에 마춰서 동작하는건가요?
그럼 위쪽으로는 유저모드인데 어떤식으로 동작하는지 감이 안잡히네요.. 여기서 IO메니저는 없나요?
 
 
드라이버 통신은 IO 매니저의 의해 이루어집니다. 즉 IRP 통신입니다.
즉 dll <-> sys 사이 통신은 CreateFile, ReadFile, WriteFile, DeviceIoControl, CloseHandle을 통해 이루어집니다. 즉 장치 이름을 ms에서 알고 있기 때문에 이런 인터페이스로 개발이 되었을 겁니다.

 
질문9
 TDI쪽 노란색 계층들도 NDIS의 초록색 계층들이 NDIS인터페이스에 맞춰서 작성되는것처럼
 TDI의 인터페이스가 따로있어서 거기 맞춰서 개발해야하는건가요?
 
네 맞습니다. tdi 문서에 보면 인터페이스 관련 내용들은 자세하게 나와 있습니다.

 
질문10
우리가 NDIS인터페이스에 맞춰서 드라이버를 개발하지만
실제로는 NDIS라이브러리가 윈도우즈의 드라이버 동작방식에
맞춰서 변환해주는건가요?
 
 
ndis 라이브러리의 내부 구조는 wdm 구조일 겁니다.

 
질문11
 이렇게까지 많은 계층들이 필요가 한가요?
 이렇게 여러단계로 나눠논 이유가 무엇인가요??
 
 
third party 개발을 위한 구조입니다. 그리고 os 의 아키텍처입니다. os 개발을 잘하기 위한 구조입니다.

 
한 반년동안 제대로 이해안되던 질문들입니다 ㅠㅠ
정확한 동작을 이해하기가 엄청 어렵네요
항상 답변해주시는 운영자님 감사합니다^^
수고하세요^^
 
 
운영자님 답변 정말 감사합니다^^
 많은 걸 이해하게 됐습니다^^
 
근데 또 질문이 있어요 하하~
프로토콜 드라이버를 보면 TCPIP.sys 란 파일있잖아요
여기는 IP기반 패킷만 이 드라이버로 가는건가요?
IPX라든가 IP기반이 아닌 패킷들은 다른 프로토콜 드라이버로 올라가잖아요


질문 1
 그렇다면 미니포트에서 이더넷 프레임을 검사해서 적절한 프로토콜 드라이버로 올리는 건가요?

미니포트에서는 바인딩된 모든 프로토콜 드라이버에 패킷들을 인디케이트합니다. 프로토콜 드라이버에서 자기 패킷이 아니면 드랍을 하는 방법입니다.

질문 2
 이더넷 헤더는 어디서 붙이고 버리나요?(?)
 TDI에서는 이더넷 헤더를 얻을 수 없다고 알고 있거든요

tdi에서 다루는 구조는 이더넷 프레임을 다루는 게 아니고 연결 관리를 핸들로 처리하기 때문에 즉 연결을 캡슐화해서 처리합니다. 즉 소켓 단위라고 생각하시면 될 겁니다. 그래서 이더넷 헤더를 파악할 수 없습니다.

질문 3
 TDI 클라이언트를 개발한다면
 이것두 병렬구조로 붙게 되나요?

네 그렇게 되겠죠.. 

질문 4
 Hook Driver라는건
 네트워크 계층에서 어떤 드라이버에도 붙일 수 있는건가요?

hook 방법을 이해하시면 좀 더 이해가 쉬울 겁니다. 훅은 함수 포인터를 훅하는 것이기 때문에 원본 함수 포인터를 알면 모든 함수들이 훅이 가능합니다. 네트워크 계층에 상관이 없습니다.

질문 5
 Ip Filter Hook Driver는 어떤 드라이버에 붙은 필터드라이번가요?

tcpip.sys에서 export한 필터 함수입니다. 그래서 기능이 제한되었습니다. 즉 제공된 함수이외의 기능은 불가능합니다.

질문 6
 TDI 계층에서도 어퍼에지 로워에지라는 개념이 있나요?

다른 이름으로 사용합니다. transport와 client 개념입니다. 통신 방법도 차이가 있습니다.

질문 7
 TDI를 개발하지 않고도(IM이나 HookDriver에서)
 소켓의 생성을 감지하고 차단할 수 있을까요?

소켓의 생성이라는 말의 의미에 따라 다릅니다. 소켓의 생성이 인터넷 차단인지 아니면 실제 소켓 함수의 차단인지에 따라 차이가 있습니다. 원하는 기능이나 구조에 따라 훅 방법과 접근 레이어가 달라집니다.

질문 8
 LSP계층에 대한 어떤 문서나 사이트는 없나요?
 이쪽은 자료가 전혀 없는거 같던데 ㅠㅠ

sdk에 샘플 코드가 있고 msdn 도움말과 과거 한국전산원에서 프로젝트로 한 문서가 있습니다.
그리고 lsp를 사용한 스팸 메일 차단 공개 프로젝트가 있습니다.

질문 9
 paathru예제를 보면 모든 callback(?)함수들을 다 구현해 주던데요
 보통 필터 드라이버에서 보면
 자신이 필요한 동작만 프록시함수를 만들어서 연결시켜주잖아요
 IM에서는 모든 동작을 다 정의해줘야 하나요?

훅 드라이버와 차이점입니다. 훅방법은 자신의 훅할 위치만 훅하면 되지만 im은 ndis 아키텍처입니다. 이 구조에 맞춰 개발을 해줘야 합니다.

질문 10
 윈도우 방화벽은 무슨 드라이버로 제작된건가요?

분석을 안해봐서 어떻게 개발되었는지는 모르겠습니다.
분석을 하실 때는 일단 사용된 바이너리를 검색하시고 바이너리를 역어샘블이나 바이너리 십육진 덤프등등의 리버스 엔지니어링 툴들을 사용해서 분석해 보세요.

질문 11
 미니포트 드라이버는 왜 미니포트라고 부르는건가요?
 
또 질문 많이 하게 되네요^^

과거 랜카드 드라이버는 풀 닉드라이버라고 했습니다. 말 그대로 입니다. 포트는 하드웨어와 통신을 하는 최단부분입니다. 버스 포트 등등... 미니는 최소 업체 스펙만 구현을 하면 되도록 os에서 전체 구조를 제공해주었기 때문에 미니 부분만 개발을 하면 되는게 아닌가 생각이 듭니다. 정확히 모르겠네요.. 정의에 대해서는 



-----------------------------------------------------------------------------------


sfilter.dll은 



NTDDK\src\network\config\filter를 build하면 sfilter.dll이 생성된다고 합니다.



저의 경우에는 ddk sample설치시 골라서 설치해서 이 폴더가 없었던것 같습니다.



이 파일의 기능은 hantech에 netcoder님이 잘 설명 해주셨더군요.



설치 관련 dll입니다.

notify object으로써 동적으로 설치 관련 부분을 담당합니다.

즉 프로토콜을 등록하면서 가상 미니포트를 등록하려하면 이 dll 안에서 설치 관련 연산을 하면 됩니다.

2003 dotnet ddk에서는 passthru의 notify object은 사용을 안해서 제거를 했습니다. mux에서는 이 부분을 사용해서 (프로토콜 + 가상 미니포트) 먼저 네트워크 등록 정보에서 muxp 프로토콜을 등록을 하면 네트워크 구성 서브시스템(네트워크 설치 관련 모듈:운영체제)에서 notify object(CoM)을 호출을 하면 이 내에서 가상 미니포트를 등록을 합니다.



즉 프로그램 상으로 설치 과정을 변경하려면(네트워크 등록 정보에서 새로운 프로퍼티 sheet 추가 등등) 이 dll을 등록을 해야 합니다.(inf 파일 내에 component dll 부분에)



보다 자세한 내용은 ddk의 네트워크 부분에서 install 부분을 참조하세요.

자세하게 나와 있습니다.

'Programming > WinDriver' 카테고리의 다른 글

NDIS Driver 01) 시작  (0) 2010.05.02
DDK 개발 환경 구축  (0) 2010.04.18
_LIST_ENTRY  (2) 2010.03.18
Lookaside list  (0) 2010.03.18
Fast I/O  (0) 2010.03.18

MTU (Maximum Transmission Unit) ; 최대 전송 단위
MTU[엠티유]는 TCP/IP 네트웍 등과 같이 패킷 또는 프레임 기반의 네트웍에서 전송될 수 있는 최대크기의 패킷 또는 프레임을 가리키며, 대개 옥텟을 단위로 사용한다.
TCP는 어떠한 전송에서라도 각 패킷의 크기를 결정하는데 있어 MTU를 사용한다.
MTU가 너무 크면 커다란 크기의 패킷을 처리할 수 없는 라우터를 만났을 때 전송 해야하는 경우가 생길 수 있다. 이와는 반대로 MTU가 너무 작으면, 대적으로 헤더 및 송수신 확인에 따르는 오버헤드가 커지게 된다.
대부분의 컴퓨터 운영체계에서는 기본적으로 대부분의 사용자에게 두루 적합한 MTU 초기치를 제공한다. 그러나, 일부 사용자들은 이 MTU 값을 변경해야할 필요가 있다.
일반적으로, 인터넷 사용자들은 MTU 기본 값을 바꿀 것인지 또는 바꾼다면 얼마로 꾸어야하는지에 대해 자신의 인터넷 서비스 공급자들의 충고를 따르는 것이 좋다.

윈도우95 사용자들의 기본 MTU 값은 1500 옥텟이며, 이것은 이더넷의 표준 MTU 값과 같다. 인터넷의 사실상의 표준 MTU는 576이지만, ISP들은 종종 1500을 사용할 것을 제시한다. 만약 웹사이트를 액세스하다가 MTU 크기가 576으로 설정되어 있는 라우터를 빈번하게 만나게된다면, 그 크기로 변경하는 것이 나을 수도 있다
(실제로는 어떻든 몇몇 사용자들은 MTU 설정을 576으로 해서 성능이 향상되었다고 주장하는 사람도 있고, 또 일부는 아무런 향상이 없다고 말하기도 한다). MTU의 최소치는 68로 설정할 수 있다.

윈도우98에서는 그들의 접속이 1500을 써야하는지 또는 576을 써야하는지를 감지할 수 있어서, 그 접속에 적합한 MTU를 선정할 수 있게 해준다. 기본 설정 값은 "자동(Automatic)"이지만, 사용자가 패킷 크기를 1500, 1000 또는 576 등과 같이 명시적으로 설정할 수도 있다. TCP 외의 프로토콜들에는 다른 MTU 크기가 적용될 수 있다.


=============== 또 다른 정의 ==============================
MTU (Maximum Transmission Unit)은 네트워크 상에 최대 전송 단위.
주어질 물리적 매체 상에서 전송 가능한 데이터의 최대 단위를 말한다. .
예) 이더넷의 MTU는 1500바이트이다

MTU란 네트워크 상에서 Maximum Transmission Unit이라는 것은 한번의 물리적인 프레임상에 전송될 수 있는 최대크기의 데이타 또는 패킷을 이야기한다. 이 패킷은 네트워크상에서 라우터가 필요로 하는 패킷의 주소와 같은 보를 싣고 있는 헤더와 트레일러(꼬리) 정보를 가지고 있다. 만약 페킷이 패킷프레임보다 더 작은 MTU를 가지고 있는 네트워크로 보내진다면 이 패킷은 불행히 쪼개져야(fragmentation,단편화) 한다. 그리고 이 조각들은 다시 조합되어야 하므로 결국은 성능저하가 생기게 되는 것이다.

MTU는 보통 MSS(Maximum Segment Size)와 RWIM(TCP Receive WINdow)와 충돌을 일으키게 되는데, MSS는 winsock이 접속 중에 받아들이려고 하는 최대 TCP데이타의 크기를 이야기한다. MSS는 MTU보다 적어도 40바이트이상 작아지는데, 이 사이즈는 헤더와 트레일러 정보 때문에 생기는 차이다. RWIN은 데이타를 받는 컴퓨터가 받기를 준비하는 데이타의 크기를 말한다. 만약 RWIN이 너무 크게 맞춰져 있다면, 하나의 패킷이 손상되거나 잃어버리게 되었을 때, 데이타의 손실이 너무 커지게 된다.

그리고 너무 작게 맞춰져 있을 때는(예를 들어, 1 x MSS), 전송이 아주 늦어지게 되는 것이다. 일반적으로 RWIN은 4x, 6x, 8x MSS 로 맞춰진다.

TCP/IP의 최대 속도는 SLIP(Serial Line Protocol)이나 PPP(Point to Point Protocol)접속을 통해 전송될 때, 무엇보다도 모뎀의 속도에 의해 결정된다. 이상적으로 생각한다면, 28.8Kbps(kilobits/s)의 속도 에서 3.2KBytes/sec의 속도를 가질 수 있어야 하고, 24Kbps접속에서는 2.7KBytes/sec의 속도를 가져할 것이다. 하지만 전송되는 TCP데이터율은 한 Byte/sec당 9bps의 모뎀 연결율(modem connect rate)를 필요로 한다.

윈도우즈의 Programs/Accessories/System 에 있는 Windows System Monitor (sysmon.exe)를 이용하면, 당신의 접속 속도를 쉽게 체크해 볼 수 있다. 데이타 전송률을 볼 수 있는 더 좋은 방법은 'Net.Medic'이라는 현재 사용하는 인터넷 브라우저와 함께 사용되는 프로그램이 있다. 이 프로그램은 인터넷을 사용하는 도중에 일어나는 문제들을 고쳐주거나, 해결방안을 마련해주도 상황들을 모니터할 수 있는 프로그램이다.

위에서 말한 데이타 전송률이라는 것은 통신상에서 획득할 수 있는 이상적인 속도를 얘기한다. 그러나 종종 네트워크 상에 보내기 전에 인터넷의 중간 IP 라우터들에서 TCP/IP요구를 조정하거나 MTU의 크기를 더 작게 다시 나누거나 하는 과정에서 이 속도는 많이 느려지는 것이다.

여러 웹 사이트들을 방문할 때, 아마도 576바이트의 IP 디폴트 MTU의 패스로 다운로드하는 라우터를 적어도 하나 이상은 만날 것이다.
그러면,이때, 당신과 또 TCP서버가 TCP 세그먼트(MSS)를 536바이트보다 크게 사용하고 있다면, 패킷을 나누기 위해 다시 느려지는
결과를 낳게 될것이다. 파일 다운로드 스피드에 상당한 영향을 미쳐 웹이나 e-mail 프로그램에서 텍스트 데이타를 받을 때나 fragmentation을 줄이는 것이 통신 환경을 개선하는 가장 중요한 부분이 될 것이다.


MTU =1500 과 576 의 차이
답> 아이넷에서는 MTU=576로 세팅하니 엄청 느려지고 인터피아에서는 꽤 빨라졌습니다.
그런데 역시나 http://www.krnic.net/net/image/connect9710.gif 을 보았더니 인터피아는 데이콤과 코넷에 E1, 미국과 T1 두개로 연결되어 있더군요. 즉, 위의 그림을 보시고 자기 ISP에서의 MTU를 최대로 쓸지 최소로 쓸지 결정하시기 바랍니다.

MTU 조절기는 http://www.iworld.net/tucows/adnload/dlmtuspeed.html 에서 다운로드 가능합니다.
먼 저, Internet의 연결된 Network Device들은 보통 MTU =1500의 Option을 사용합니다. 물론 RFC1063에 따르면 ETHERNET=1500 , POINT-TO-POINT=1500 , X.25=576 , SLIP=1006 , 등 여러 가지로 나뉘어지지만, 기본적으로 Router 및 WAN Switch로 구성된 INTERNET에서는 MTU를 1500을 사용합니다.(cisco systems 및 BayNetwork Router에서는 Default로 구성 시에 MTU=1500으로 되고, 또한 Frame-Relay 및 ATM OC-3에서도 이 Rule이 적용됩니다) 현재 WIN95 및 WINNT , HP-UX , Solaris 등 TCPIP Kernel에서는 Path-MTU -Discovery라는 Option을 사용하고 있어서 IP Header에서의 DF Bit(Don't Fragment Bit)를 1로 Marking 하여 보내고 있습니다. 이것의 의미는 자신이 보낸 IP Packet에 대해 Fragment를 허락하지 않는다는 내용입니다. ( HPUX의 경우 nettune명령으로 Option조절가능 ) 하지만 IBM MVS/TCPIP 및 Linux Old-version같은 경우는 사용을 않합니다. 만약 이러한 Frame이 Internet상의 MTU =576으로 설정되어 있는 임의의 Router로 routing 되었을 때,이 해당 Router는 Fragment를 하려하나 DF Bit이 1로 되어 있어 실패하고 해당 IP Source에게 "ICMP Type=3 Code=4 Fragment Need , but DF Bit=1"의 Message를 보내게 됩니다(Header에 Next-Hop MTU를 포함하여).이것을 Client에서 받았을 때에는 PMTU의 크기를 해당 Next-Hop MTU에 맞추어 줄여서 보내게 되고, 또한 RoutingPath 변경으로 인한 PMTU 증가는 Timer로 주기적(2분 또는 10분)으로 PMTU Size를 증가하여 ICMP Message를 받을 때 까지 MTU Size를 증가 시킨 후 DF=1로 Marking하게 됩니다. 이러한 Internet상에서의 Routing Path변경이 흔하지 않으므로 이 같은 MTU Size증가는 드물게 일어납니다 (만약 Firewall에서 이러한 ICMP Type을 Deny했다면 MTU Size가 틀리고 DF=1로 인해 Router가 Client에게 알려주려는 ICMP Message가 유실되어 Client측에서는 아무런 조치도 못하고 멍청하게 Hold되어 버립니다

외국 News Group에 이런 내용으로 하소연하는 Network Administrator을 많이 보았습니다,이런 경우에는 Sniffer또는 Network Monitor로 Packet을 Dump하여 초기 TCP Handshake때에 MSS(아래부분에 설명)를 확인하여 틀릴 경우에 1.MTU를 작은 쪽으로 맞추어 주거나 2.Firewall에서 ICMP Deny를 삭제하여준다)
-ICMP Type=3 Code=4 Message
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type =3 | Code =4 | Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| unused =0 | Next-Hop MTU |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Internet Header + 64 bits of Original Datagram Data |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* 이전에는 Next-Hop MTU가 없었으나 RFC1191에서 Propose된 후에 추가 되었슴. 또한 TCP Header의 초기 3-Way Handshake시에 Option Field의 MSS가 있는데 이것도 MTU 와 관계가 깊습니다. MSS란 Maximum Segment Size로 TCP Stack이 Sliding Window Buffer에서한번에 전송할 수 있는 Data Size수가 됩니다.보통 MTU -20Byte(IP Header) -20Byte(TCP Header)로 계산 되어 설정됩니다.
보통 MTU 를 1500사용 하므로 MSS=1460 증 한번의 TCP Packet전송으로 보낼 수 있는 Data Size는 1460 Byte가 되는 거죠.
초 창기 Internet에서는 TCP가 단순하게 IP Destination이 Non-Local일 경우에 536(576- 20-20)으로 설정하고 Local인 경우에는 1460(1500-20-20)로 설정하였다-아직도 IBM MVS/TCPIP는 이 Rule을 사용하고 있다 (IBM/MVS Tcpip Parameter에 Default로 놓을 경우 이렇게 되고 MTU를 1500으로 바꾸려면 해당 Network에 직접 1500을 기술하여야 한다, 이렇게 바꾸더라도 역시 PMTU 는 사용하지 못한다- DF Bit=0.역시 IBM은 Internetwrking 보다는 SNA로만 장사해야 될 것 같다 ) 물론 MSS Size는 초기 MSS Negotiation시에 작은 수로 맞추어 집니다.

octet ; 옥텟
컴퓨터에서의 옥텟은 8 비트의 배열을 말한다. 그러므로, 옥텟 한 개는 일반적으로 8 비트로 구성된 한 바이트와 같다.
그러나, 모든 컴퓨터 시스템이 8 비트를 1 바이트로 사용하지는 않기 때문에, 8 비트 한 셋을 일컫는 분명한 의미 제공을 위해 옥텟이라는 용어가 사용된다.

이 용어를 8진수의 의미를 갖는 octal과 혼동해서는 안된다.


octal ; 8진법

Octal은 8진법을 가리키는 용어이다. 8진법에서는 숫자들이 0, 1, 2, 3, 4, 5, 6, 및 7 등 8가지의 문자를 이용하여 구성된다.
7 다음의 숫자는 10이며, 17 다음의 숫자는 20 등으로 변해나간다. 컴퓨터 프로그래밍에서, 8진수는 2진수에 비해 짧게 표기할 수 있다는 장점 때문에 2진수 대신 사용되는 경우가 있다.

'Programming > 이것저것' 카테고리의 다른 글

CISC, RISC, CRISC(EPIC)  (0) 2010.03.18
펜티엄부터 린필드 i5까지, 인텔 어떻게 걸어왔나  (0) 2010.03.18
ICMP  (0) 2010.03.18
TCP/IP PPT 에서 뜯어왔음ㅋ  (0) 2010.03.18
OSI 7Layer  (0) 2010.03.18
1. ICMP란?

ICMP(Internet Control Message Protocol)는 기술적으로 오류보고 메커니즘(Error Reporting Mechanism)입니다. ICMP는 오류를 감지한 라우터가 최초 근원지에 오류를 보고할 수 있는 방법을 제공합니다. 호스트 서버와 게이트웨이 사이에서 메시지를 제어하고 에러를 알려주는 프로토콜로서 RFC 792에 명시되어 있습니다.

데이터그램이 오류를 유발하면, ICMP는 데이터그램의 최초 근원지에만 오류 상태임을 보고할 수 있습니다. 중계 라우터의 문제를 알려줄 수 없기때문에, 사실상 어떤 라우터가 문제를 일으켰는지 판단할 수 있는 확률이 낮습니다.

그럼 왜 ICMP는 최초 근원지에게만 오류를 보고할까요? 데이터그램에는 출발지와 최종 목적지 주소만 지정할 수 있기 때문입니다. 따라서 지나가는 경로에 대해서는 알 수 있는 길이 없습니다.

Snap3.bmp
2. ICMP 메시지 전달

ICMP 메시지는 두 단계의 캡슐화 과정을 거칩니다.
ICMP 데이터영역 + ICMP 헤더

데이터그램 데이터영역          + 데이터그램 헤더

프레임 데이터영역                                  + 프레임 헤더
ICMP 메시지는 IP를 이용합니다. 즉, OSI Layer 3계층에 해당하는 프로토콜입니다.
IP 데이터그램에 캡슐화도고 IP를 통하여 전송이 됩니다.

ICMP 메시지는 오류 메시지를 전송하지만, 메시지 자체의 오류에 대한 ICMP 메시지는 생성되지 않습니다.


3. 메시지 포맷

ICMP는 세가지의 필드로 이루어져 있습니다.

"TYPE"필드 - 8비트이며, 메시지를 식별하는 일을 합니다.
"CODE"필드 - 8비트이며, 메시지 타입에 대한 추가적인 정보를 제공합니다.
"CHECKSUM"필드 - 16비트이며, 체크섬을 제공합니다.

오류를 보고하기 위한 ICMP 메시지는 헤더에 추가적으로 문제를 발생시킨 데이터그램의 옥텟을 포함합니다.
오류 발생시 어떤 애플리케이션이 문제를 일으킨 것인지 정확하게 알기 하기 위해서, 문제를 유발시킨 데이터그램의 부분을 직접적으로 되돌려 주는 것입니다.

* 참고 : ICMP TYPE 별 메시지 종류

 TYPE 필드

 ICMP 메시지 종류

 0

에코 응답(echo reply) 

 3

목적지 도달 불가능(destination unreachable) 

 4

 근원지 억제

(source quench)

 5

경로 변경(redirect) 

 6

 대체 호스트 주소

(alternate host address)

 8

 에코 요청(echo request)

 9

 RA(router advertisement)

 10

 RS(router soliciation)

 11

 데이터그램에 대한 시간 초과

(time exceeded for a datagram)

 12

 데이터그램의 파라미터 문제

(parameter problem on a datagram)

 13

 타임스탬프 요청(timestamp request)

 14

 타임스탬프 응답(timestamp reply)

 15

 정보 요청(information request)

 16

 정보 응답(information reply)

 17

 주소 마스크 요청

(address mast request)

 18

 주소 마스크 응답

(address mask reply)

 30

 Traceroute



4. PING

ping은 사용자가 ICMP echo request를 보낼 수 있도록 하는 명령어입니다. 이것은 네트워크 문제를 식별하기 위하여 사용을 하는데, 호스트가 ICMP echo request 메시지를 목적지로 전송합니다. 그리고나면 echo request 메시지를 받은 대상은 echo reply 메시지를 전송받은 쪽으로 되돌려 주어야 합니다. 이렇게 echo request와 echo reply 메시지를 주고 받음으로 인해서 호스트는 목적지에 도달 가능한 지, 응답을 하는지 검사하기 위해 사용됩니다.

따라서 이 성공적인 응답을 통해서 시스템의 주요 부분들이 제대로 동작하는지 확인할 수 있습니다.

이렇게 정상적인 응답이 가능하기 위한 다음과 같은 조건들이 있습니다.
1. 호스트 컴퓨터의 IP 소프트웨어는 데이터그램을 포워딩할 수 있어야 합니다.
2. 호스트와 목적지 간의 중계 라우터가 동작 중이고, 데이터그램을 정확히 전달해야 합니다.
3. 목적지 컴퓨터는 동작중이어야 하고 ICMP와 IP 소프트웨어가 동작해야 합니다.
4. 응답이 되돌아오는 경로에 놓인 모든 라우터들의 라우팅 테이블 정보가 전달 가능한 경로를 구성해야 합니다.


* 참고 : ICMP destination unreachable 메시지

 Code 값

의 미 

 0

네트워크 도달 불가능 

 1

 호스트 도달 불가능

 2

 프로토콜 도달 불가능

 3

 포트 도달 불가능

 4

 단편화가 필요하지만 DF 비트가 설정됨

 5

 소스 라우팅 실패

 6

 목적지 네트워크를 알 수 없음

 7

 목적지 호스트를 알 수 없음

 8

 근원지 호스트가 격리됨

 9

 관리상의 이유로 목적지 네트워크와의 통신이 금지됨

 10

 관리상의 이유로 목적지 호스트와의 통신이 금지됨

 11

 TOS에 대한 네트워크 도달 불가능

 12

 TOS에 대한 호스트 도달 불가능

 13

 관리상의 이유로 통신 필터에 의해 금지됨

 14

 호스트 우선순위 위반

 15

 사실상 우선순위 미달


'Programming > 이것저것' 카테고리의 다른 글

펜티엄부터 린필드 i5까지, 인텔 어떻게 걸어왔나  (0) 2010.03.18
MTU  (0) 2010.03.18
TCP/IP PPT 에서 뜯어왔음ㅋ  (0) 2010.03.18
OSI 7Layer  (0) 2010.03.18
광역 변수  (0) 2010.03.18

Snap1.pngSnap2.pngSnap3.pngSnap4.pngSnap5.pngSnap6.pngSnap7.png

'Programming > 이것저것' 카테고리의 다른 글

MTU  (0) 2010.03.18
ICMP  (0) 2010.03.18
OSI 7Layer  (0) 2010.03.18
광역 변수  (0) 2010.03.18
Virtual Function  (0) 2010.03.18

프로토콜은 한마디로 통신규약입니다.

예를 들자면:

SERIAL , 페러렐 (예전 프린터에서 많이 사용하던 방식), IEEE방식,USB,ETHERNET등

다양하지요.

그리고 프로토콜군이라 함은

각각의 통신에도 세분화가 많이 되어 있는데 (SERIAL도 RS-232,RS-422,RS-485등,

USB 1.0, 1.1, 2.0등) 이걸 세분화 하지 않고 집단으로 총칭하는 것을 프로토콜군이라고 표현하는 듯 하네요.


장비나 컴퓨터를 만드는 회사들은 세계에 수도 없이 많은데 서로 통신함에 있어서 규칙을 만들어서 범용화를 시키고 발전시키면서 오늘날에 도달한것입니다.

컴퓨터 발전에도 이 프로토콜이 없었다면 훨씬 뒤쳐진 발전을 했으리라 생각됩니다.


다 타이핑하자면 기니까 아래 기술 문서를 퍼왔으니 참조하시기 바랍니다.



그리고  OSI7계층에 대한 설명도 아래에 있으니 참조바랍니다.


프로토콜의 정의:


정보기기 사이 즉 컴퓨터끼리 또는 컴퓨터와 단말기 사이 등에서 정보교환이 필요한 경우, 이를 원활하게 하기 위하여 정한 여러 가지 통신규칙과 방법에 대한 약속 즉, 통신의 규약을 의미한다.

통신규약이라 함은 상호간의 접속이나 절단방식, 통신방식, 주고받을 자료의 형식, 오류검출방식, 코드변환방식,전송속도 등에 대하여 정하는 것을 말한다. 일반적으로 기종()이 다른 컴퓨터는 통신규약도 다르기 때문에, 기종이 다른 컴퓨터간에 정보통신을 하려면 표준 프로토콜을 설정하여 각각 이를 채택하여 통신망을 구축해야 한다. 대표적인 표준 프로토콜의 예를 든다면 인터넷에서 사용하고 있는 TCP/IP가 이에 해당된다.

정보통신의 상대방은 일반적으로 원격지에 있다. 따라서 정보를 전송하기 위해서는 정보를 전기적인 신호의 형태로 변환하고 그 변환된 신호가 통신망을 통해 흐르도록 하는데, 통신망에는 정상적인 신호의 흐름을 훼방하는 여러 가지 현상이 존재하게 된다. 이러한 현상은 정확한 정보의 전송을 방해하여 도중에 오류가 발생되는 원인이 된다.

프로토콜이라는 규약의 집합 속에는 이러한 오류에 대응하기 위한 약속이 대단히 중요하다. 또한 정보를 정확하고 효율적으로 전송하기 위해서는 송수신 개체 간에 서로 정보의 전송 시점과 수신 시점을 맞추는 일(동기화)도 수행해야 하고, 정보 흐름의 양을 조절하는 흐름 제어방법도 역시 사전에 약속하여 프로토콜 속에 포함해야 한다.

이러한 오류제어, 동기, 흐름제어, 코드변환, 전송속도 등에 대한 약속 이외에도 통신하는 상대방의 위치에 따라 통신 개체가 어느 OSI 계층에 있는 가와 효율적인 정보전송을 위한 기법, 정보의 안전성(보안)에 관한 약속들도 프로토콜의 범주에 포함되어야 한다.


OSI


네트워크는 수많은 컴퓨터와 장비로 이뤄져 있다. 신기한 것은 이들 구성요소들이 모두 말이 통한다는 것. 장비의 개발업체도 다르고 사용하는 운영체제도 다르지만, 네트워크를 통해 서로 통신을 할 수 있는 것은 바로 프로토콜 때문이다. 때문에 프로토콜은 네트워크가 성립되기 위한 가장 기본적이 요소 중 하나다.
이제 일반명사라고 해도 과언이 아닐 정도로 많이 사용되는 프로토콜은 원래 외교협약같은 좀더 고상한 용어다. 즉 말이 통하지 않는 두 장비가 의사소통을 하기 위한 절차나 규칙 등을 체계적으로 정리해 놓은 것이다.


OSI 참조모델에 대한 오해
초기의 네트워크 역시 프로토콜에 따라 통신을 했다. 하지만 OSI 7계층 참조모델(Open System Interconnection Reference Model)이 등장하기 전까지의 네트워크 프로토콜은 IBM의 SNA나 DEC의 DECNet처럼 특정 업체가 자사의 장비들을 연결하기 위해 만든 것들이었다. 따라서 서로 다른 네트워크 간에는 호환되지 않는다는 한계를 갖고 있었다.
OSI 7계층 참조모델은 이런 문제를 해결하기 위해 ISO가 제정한 것이다. OSI 참조모델은 네트워크 통신의 전 과정을 7계층으로 나누고, 각 계층마다 일정한 역할을 수행하도록 해 하나의 네트워크 통신이 완성되는 과정을 나타낸 것이다. 말 그대로 “이런 식으로 프로토콜을 만들면 서로 호환될 수 있으니, 프로토콜들은 이것을 참조하라”는 것이다. 
OSI 참조모델에 대한 가장 큰 오해는 바로 모든 네트워크 프로토콜이 OSI 참조모델에 따라 7계층 구조를 갖고 있을 것이라고 생각하는 것이다. 
네트워크는 목적에 따라 두세 단계의 프로토콜만으로도 원하는 통신을 할 수 있다. 따라서 억지로 7단계로 통신 절차를 나눌 필요는 없다. 실제로 우리가 사용하는 네트워크 프로토콜과 OSI 참조모델이 직접적으로 대응되는 경우는 그리 많지 않으며, 많은 프로토콜이 OSI 참조모델의 여러 계층에 걸친 기능을 제공한다. “이 프로토콜은 3~4계층에서 동작한다”는 말을 많이 듣게 되는 것도 이 때문이다. 
이런 특징 때문에 OSI 참조모델은 초보자가 네트워크를 이해하는 데 더없이 훌륭한 교재가 되고 있다. OSI 참조 모델은 실제 네트워크 프로토콜을 이해하기 쉽도록 만들어, 네트워크 프로토콜의 역할과 구조, 나아가 네트워크의 동작 방식을 쉽게 이해할 수 있도록 해준다.


계층화된 프로토콜의 역할
(표 1)은 OSI 참조 모델을 정리한 것이다. 여기서 가장 아래 부분인 물리 계층부터 각각의 계층마다 고유의 작업들이 정의돼 있다. 
또한 각 계층은 반드시 자신의 영역에서 운영되는 하위 계층을 통해 서비스를 받고, 상위 계층으로 서비스를 제공하도록 규정돼 있다. 예를 들면 3계층의 네트워크 계층은 2계층인 데이터링크 계층을 통해 서비스를 받고, 상위 계층인 전송 계층에 작업한 내용을 서비스하는 식이다.
한편 각 계층은 전송 데이터에 각 계층에서의 요구 조건과 처리 정보를 포함한 헤더라는 고유의 제어 정보를 전달 메시지에 추가해 다음 계층으로 보내며, 수신측의 동일 계층에 의해 해석돼 처리된다. 예를 들면 송신측 컴퓨터의 5계층에서 추가된 헤더는 수신측 컴퓨터의 5계층에서 해석되며, 해석된 헤더는 지정된 작업을 수행한 다음 제거된 상태로 다음 계층으로 넘어가, 최종적으로 수신측 컴퓨터에는 데이터만 전송된다.
이때 각 계층 간에 전달되는 데이터의 단위는 계층에 따라 서로 다른 이름으로 불리며, 이를 ‘서비스 데이터 단위’라고 한다.
프로토콜이 데이터를 전송하기 위해 사용하는 기본 단위를 PDU(Protocol Data Unit)라고 한다. 즉, 물건을 운반할 때 상자 단위로 포장해 운반하는 것과 같이 프로토콜은 정보의 운반을 위해 PDU라는 상자를 이용하는 것이다. 
상자 단위로 물건을 포장해서 운반할 때 상자마다 물품의 내용이나 발송처, 수신처 등을 표기하는 것과 마찬가지로 PDU에도 사용자 정보뿐만 아니라 데이터의 발신처와 수신처에 대한 주소 정보와 전송 중에 에러가 발생했는지 확인하기 위한 패리티, 그밖에 흐름 제어 등을 위한 각종 정보가 함께 들어간다.
계층화된 프로토콜에서는 계층마다 PDU 이름을 독특하게 붙여 사용하는 경우가 있다(표 2). 2계층 PDU는 프레임(Frame), 3계층 PDU는 패킷(Packet), 4계층 PDU는 세그먼트(Segment) 등으로 부르는 것이 일반적이다. 그리고 특별한 이름이 없는 경우에는 그냥 몇 계층의 PDU라고 부른다. 특히 세그먼트라고 불리는 4계층 PDU는 TCP에서 사용하는 경우가 많다.



TCP/IP와 OSI 참조 모델
일반적으로 가장 많이 사용되는 TCP/IP를 통해 OSI 참조 모델과 프로토콜에 대해 알아보자.
TCP/IP는 좁은 의미로는 1969년 미국방부가 제시한 ARPNET (Advanced Research Projects Agency NETwork)에서 제안한 프로토콜의 집합 중 인터네트워킹에 대한 핵심적 기능을 제공하는 TCP와 IP만을 지칭한다. 하지만 OSI의 3계층에서 7계층까지 해당 소프트웨어나 서비스 관련 프로토콜을 통틀어 얘기할 때도 사용한다.
TCP/IP는 3계층 프로토콜인 IP와 4계층 프로토콜인 TCP가 합쳐진 용어다(그림 2). 네트워크 계층에 해당하는 IP는 네트워크 환경에 흩어져있는 여러 노드 중에서 지정된 목적지를 찾아가는 경로를 설정하는 작업을 수행하고, TCP는 안정된 데이터 전송을 위해 흐름과 오류를 제어하는 역할을 맡는다.
TCP 외에 또 다른 4계층 프로토콜 중 하나인 UDP(User Datagram Protocol)는 TCP와는 달리 데이터의 신뢰성있는 전송을 보장하지는 않는다. 그러나 신뢰성이 매우 높은 회선을 사용하거나 데이터의 확실한 전송을 요하지 않는 통신, 또는 한번에 많은 상대에게 메시지를 전송할 경우에는 보다 효율적이다.
일반적인 고속 이더넷 환경에서 FTP를 통해 서버에 접속하는 경우를 OSI 참조 모델을 통해 생각해 보자. 우선 클라이언트의 FTP 클라이언트는 애플리케이션 계층의 프로토콜인 FTP 규격에 맞춰 데이터에 헤더를 붙여 하위 계층으로 전송하고, 4계층 TCP 프로토콜이 수신측 서버의 4계층과 통신을 통해 데이터의 정합성을 테스트하고 오류가 있을 경우 재전송을 하는 등의 일을 처리한다. 또한 3계층에서는 IP 어드레스를 통해 송신측이 특정 수신측을 지정하고 경로를 설정한다.
그 아래의 2계층과 1계층에서는 두 노드 사이의 물리적인 연결과 디지털 데이터를 전기적인 신호로 변환해 전송하고 신호가 약할 경우에는 증폭하는 등의 일을 처리한다.



OSI 참조모델의 계층별 이해


물리 계층
OSI 7계층 참조 모델의 1계층은 물리 계층이다. 이 계층에서 담당하는 것은 네트워크 케이블과 신호에 대한 것으로, 물리적 신호(bit)의 전송 규칙을 조정하는 역할을 한다.
물리 계층은 전송 매체에 대한 규정은 정하지 않지만, 이를 구현하는 방법적인 면에서는 전송 매체와 깊은 관계를 맺고 있다. 참고로 물리 계층과 관련된 네트워크 연결 장비들은 다음과 같다.


- 허브나 리피터 등의 전기적 신호를 재발생시키는 장비
- 각종 커넥터와 같은 전송 매체 연결 소자 등의 기계적인 연결 장치
- MODEM, CODEC 등 디지털/아날로그 신호 변환기


기본적으로 네트워크는 일대일 또는 멀티 포인트 방식으로 연결된다. 잘 알고 있듯이 일대일 방식은 두 통신 장비들이 직접 연결된 상태를 말한다. 이런 식으로 연결하면 회선을 전용으로 사용할 수 있으므로, 장비간 정해진 전송 용량과 대역폭을 보장받을 수 있다. 한편 멀티 포인트 연결은 3대 이상의 장비를 연결하는 방식을 말한다. 이 방식은 같은 주파수대를 공유하며, 전송 매체에 연결된 모든 장비가 전체 기능을 공유할 수 있다. 일반적으로 대규모 네트워크를 구축할 경우에는 일대일 연결과 다중점 방식을 적절히 혼합하는 방식으로 설계한다.
이 같이 다양하게 연결된 네트워크의 형태를 토폴로지라고 부른다. 즉, 어떤 형태나 구조로 연결된 것을 네트워크 토폴로지(Network Topology)라고 이해하면 된다. 단, 눈으로 보이는 물리적인 토폴로지 형태가 논리적으로는 동일하지 않을 수도 있다. 일반적인 토폴로지에는 버스형(Bus), 링형(Ring), 스타형(Star), 메시형(Mesh), 셀룰러형(Cellular) 등이 있다.
1계층에서는 이외에도 전기적인 펄스나 광학적인 방법 또는 전자기적 파동을 통해 신호를 전달하는 방법에 대한 정의도 수행하며, 동기화 방식, 대역폭 등에 대한 개념을 정의한다.


데이터 링크 계층
OSI 참조 모델의 두 번째 계층인 데이터링크 계층은 데이터 패킷을 생성하고 전송하는 방법을 규정하는 프로토콜에 대한 계층이다. 이 계층이 하는 일은 물리 계층에서 넘어오는 데이터의 오류를 검사하고 복구 기능을 담당할 뿐 아니라, 시스템 간 전송 속도 차에 의한 오류나 흐름 제어까지 도맡아 처리한다. 쉽게 얘기하자면 화물을 트럭에 싣고, 각 트럭을 고속도로로 보내며 화물이 무사히 목적지에 도착하도록 관리하는 역할을 담당한다.
다른 모든 계층과 마찬가지로 데이터링크 계층 또한 고유의 식별 정보를 전송 데이터 앞에 붙이고 있다. 이 정보에는 수신자와 송신자(물리적 또는 하드웨어적인)의 어드레스와 프레임 길이, 그리고 상위 계층의 정보가 포함돼 있다. 이 계층에 속하는 네트워크 연결 장비로는 브리지, 지능형 허브 등을 들 수 있다.
데이터 링크 계층의 여러 기능은 대개 MAC(Media Access Control)과 LLC(Logical Link Control)의 두 가지 계층으로 다시 세분화할 수 있다. MAC 계층은 동일 채널을 공유하는 통신 방법을 제어하기 위한 것이고, LLC 계층은 데이터 전송을 위해 각 장비들을 논리적으로 연결하고, 연결을 유지하는 역할을 담당한다.


네트워크 계층
네트워크 계층은 여러 개의 독립적인 네트워크 사이에서 데이터 전송에 관한 계층이다. 앞서 설명한 데이터링크 계층의 데이터 전송은 물리적인 장치의 어드레스 지정을 통해 단일 네트워크로 연결된 모든 장치에 데이터를 브로드캐스팅하며, 수신측 장비에서 확인해 자신에게 오는 데이터를 수신받는 방식이다. 
그러나 네트워크 계층에서는 네트워크와 네트워크를 연결하는 인터네트워킹 환경에서 특정 경로를 선택해 권한이 없는 네트워크에 데이터를 전송하는 것을 미연에 방지할 수 있다. 또한 서로 다른 네트워크로 구성된 인터네트워킹을 통해 올바른 데이터 경로를 보장할 수도 있다. 네트워크 계층에서는 기본적으로 다음과 같은 사항을 수행한다.


- 논리적으로 분리된 모든 네트워크에 고유한 네트워크 어드레스를 부여한다.
- 인터네트워크를 통해 컴퓨터와 라우터가 최적의 데이터 경로를 결정하도록 라우팅을 구현한다.
- 네트워크는 인터네트워크 내에서 예상되는 오류의 개수에 따라 서로 다른 단계의 연결 서비스를 구현한다.


전송 계층
전송 계층은 복잡한 하위 계층 구조를 상위 계층이 알 필요가 없도록 감추기 위한 계층이다. 여기서는 상위 계층의 메시지를 세그먼트화한 후, 이 세그먼트를 세션 계층이나 상위 계층 프로세스에게 신뢰성 있게 전달하는 역할을 한다. 전송 계층은 하위 계층에서의 신뢰성이 모자라는 연결 서비스나 연결 지향 연결 서비스가 갖는 미비점을 해소하기 위한 역할을 수행한다. 여기서 신뢰성이 보장된다는 말은 데이터가 항상 전달된다는 것을 의미하지는 않는다. 
예를 들어 케이블이 끊어졌을 경우에는 데이터의 전달을 보장할 수 없다. 만일 어떤 데이터가 수신측 장치에게 올바르게 전달되지 않은 경우, 전송 계층은 재전송을 개시하거나 상위 계층에게 이 사실을 통보할 수 있으며, 이에 근거해 상위 계층에서는 필요한 조치를 취하거나 사용자에게 옵션을 제공하게 된다.


세션 계층
세션 계층은 상위 계층에서 필요로 하는 서버 이름과 어드레스를 하위 계층에서 제공되는 논리 어드레스 정보를 사용해 식별할 뿐 아니라, 서비스 제공자와 요청자 간을 연결하고 대화를 개시하는 역할을 담당한다. 이 기능을 수행하는 경우 세션 계층은 각 네트워크 구성 요소를 소개하거나 식별해내며 액세스 권한을 조정하기도 한다.


프리젠테이션 계층
프리젠테이션 계층은 변환과 암호화를 통해 데이터를 주고받는 서로 다른 환경의 컴퓨터와 애플리케이션이 데이터를 이해할 수 있도록 돕는 기능을 수행한다.


애플리케이션 계층
사용자로부터 데이터를 받아 하위 계층으로 전달하고, 하위 계층에서 전달하는 데이터를 사용자에게 전달하는 애플리케이션 계층은 여러 가지 실제적인 네트워크 서비스를 제공하는 계층이다.
애플리케이션 계층에는 각각의 네트워크 서비스에 대한 특정한 주제와 기능이 포함된다. 다시 말해, 이 계층 하부에 있는 여섯 계층이 일반적으로 네트워크 서비스를 지원하는 기술과 작업을 포함하는데 반해, 애플리케이션 계층에서는 특정 네트워크 서비스 기능을 수행하는데 필요한 프로토콜을 지원한다.
애플리케이션 계층 프로토콜이 지원하는 서비스로는 네트워크 서비스에 해당하는 파일, 프린트, 메시지, 애플리케이션, 데이터베이스 서비스 등이 포함된다. 
OSI 7계층을 만든 이유는 프로토콜을 체계적으로 연구하기 위한 목적 외에도, 공용으로 사용할 수 있는 공개된 프로토콜을 만들기 위한 것도 있었다. 그러나 7계층이 발표된 시점에 이미 많은 프로토콜이 사용되고 있었고, 특히 WAN에서는 TCP/IP가 표준으로 자리잡아 독보적인 위치를 확보하고 있었다. 
그 이후, 1계층과 2계층에서는 이더넷, 3계층과 4계층에서는 TCP/IP, NetBEUI, IPX 등이 업계 표준으로 자리잡았다.
한편 5, 6, 7계층은 각각이 별도로 구현되기보다는 통합된 형태의 서비스라는 이름으로 제공된다. 텔넷, FTP, 전자우편(SMTP, POP), HTTP, 뉴스그룹(NNTP), NetBIOS 등이 이와 같은 서비스에 해당한다.

'Programming > 이것저것' 카테고리의 다른 글

ICMP  (0) 2010.03.18
TCP/IP PPT 에서 뜯어왔음ㅋ  (0) 2010.03.18
광역 변수  (0) 2010.03.18
Virtual Function  (0) 2010.03.18
Virtual Destructor  (0) 2010.03.18

프로젝트명.sln 파일을 텍스트 에디터로 연후.


------------------------------------------------------------------------------------


Microsoft Visual Studio Solution File, Format Version 10.00 <- Microsoft Visual Studio Solution File, Format Version   9.00 으로 변경


# Visual Studio 2008 <- # Visual Studio 2005 으로 변경


------------------------------------------------------------------------------------


프로젝트명.csproj 파일을 동일하게 텍스트 에디터로 연후


<Reference Include="System.Core">
   <RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Xml.Linq">
  <RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>


삭제


하단에 Project="$(MSBuildToolsPath) -> Project="$(MSBuildBinPath) 으로 변경


------------------------------------------------------------------------------------

'Programming > tool' 카테고리의 다른 글

01) XP에 DNS 설치  (0) 2010.03.19
IIS, FTP 설치  (0) 2010.03.19
Visual Studio 2008 설정  (0) 2010.03.18
NSIS 값 읽어오기  (0) 2010.03.18
NSIS 기초지식  (0) 2010.03.18

Create a Visual C++ Wizard for Visual Studio 2005

  • http://www.codeguru.com/cpp/v-s/devstudio_macros/customappwizards/article.php/c12775__1/

    Visual Studio C++ Project Templete 만들기 

  • Creating the Project

    To create a new wizard project, go to File > New > Project and select Visual C++, and then from the list of available templates customwiz. Let's call this project "DummyWin32Wizard", because after all, that's exactly what it is. You will be asked to select the settings for this project. First, put "DummyWin32Wizard" in the "Wizard Friendly Name" edit, check the "User Interface" checkbox, and set the number of pages of the wizard to 1, because that's all what we'll need.

    When the project is created, it will have several created files that you can see in the following picture. The most important ones are described here:

    get_image.png 

'scrap' 카테고리의 다른 글

명령어5  (0) 2010.03.18
명령어6  (0) 2010.03.18
LinkError 추적하기  (0) 2010.03.18
SVN 사이트  (0) 2010.03.18
Visual Studio 단축키  (0) 2010.03.18

짜증나는 워닝과 에러 중에,헤더파일 순서에 따라 발생하는 워닝/에러가 있습니다.특히 링크타임에 나는 에러는 네이밍 모양새가 재밌게 생겨먹지 않은 스타일로 생기는 데다가 링커가 별로 힌트를 주지 않아서 짜증이 나기도 합니다.예를 들면 아래와 같은 겁니다.


1>Generating Code...

1>Compiling resources...

1>Microsoft (R) Windows (R) Resource Compiler Version 6.1.6723.1

1>Copyright (C) Microsoft Corporation. All rights reserved.

1>Compiling manifest to resources...

1>Microsoft (R) Windows (R) Resource Compiler Version 6.1.6723.1

1>Copyright (C) Microsoft Corporation. All rights reserved.

1>Linking...

1>uafxcwd.lib(afxmem.obj) : error LNK2005: "void * __cdecl operator new(unsigned int)" (??2@YAPAXI@Z) already defined in LIBCMTD.lib(new.obj)

1>uafxcwd.lib(afxmem.obj) : error LNK2005: "void __cdecl operator delete(void *)" (??3@YAXPAX@Z) already defined in LIBCMTD.lib(dbgdel.obj)


위 예는 MFC프로젝트에서 모든 파일에서 MFC헤더를 다른 헤더 보다 먼저 선언해야 하는데(대부분 stdafx.h를 가장 상위에 선언합니다.), MFC프로젝트에서 사용하던 파일을 Import하고 컴파일 하는 순간 발생했습니다.


이런 에러의 경우 대처법은 의외로 간단 합니다.일단 똑똑고 기억력 좋으신 분들은 자기가 했던 행위들의 콜스택을 하나하나 거슬러 올라가시면서 대처 하는법이 있고,이게 가장 비용대비 시간단축 효가가 가장 좋습니다.


순간 욱해서 콜스택 거슬러 올라가기 힘드신 (저 같은;;)분들은 아래처럼 대처 하시면 됩니다.먼저 링커 옵션에 아래 옵션을 추가 합니다.


/verbose:lib


http://blogfiles4.naver.net/data42/2009/3/23/163/verbose_drvoss.jpg



그리고 다시 빌드 하면 링킹타임에 library를 스캔하는 리스트가 아래와 같이 output창에 나오게 됩니다.


1>Generating Code...

1>Compiling resources...

1>Microsoft (R) Windows (R) Resource Compiler Version 6.1.6723.1

1>Copyright (C) Microsoft Corporation. All rights reserved.

1>Compiling manifest to resources...

1>Microsoft (R) Windows (R) Resource Compiler Version 6.1.6723.1

1>Copyright (C) Microsoft Corporation. All rights reserved.

1>Linking...

1>Searching libraries

1>   Searching C:\Program Files\Microsoft Visual Studio 9.0\VC\lib\DelayImp.lib:

1>   Searching C:\Program Files\Microsoft SDKs\Windows\v6.0A\\lib\uuid.lib:

1>   Searching C:\Program Files\Microsoft Visual Studio 9.0\VC\lib\LIBCMTD.lib:

1>   Searching C:\Program Files\Microsoft Visual Studio 9.0\VC\lib\OLDNAMES.lib:

1>   Searching C:\Program Files\Microsoft Visual Studio 9.0\VC\atlmfc\lib\uafxcwd.lib:

1>uafxcwd.lib(afxmem.obj) : error LNK2005: "void * __cdecl operator new(unsigned int)" (??2@YAPAXI@Z) already defined in LIBCMTD.lib(new.obj)

1>uafxcwd.lib(afxmem.obj) : error LNK2005: "void __cdecl operator delete(void *)" (??3@YAXPAX@Z) already defined in LIBCMTD.lib(dbgdel.obj)

1>   Searching C:\Program Files\Microsoft SDKs\Windows\v6.0A\\lib\kernel32.lib:

1>   Searching C:\Program Files\Microsoft SDKs\Windows\v6.0A\\lib\user32.lib:

1>   Searching C:\Program Files\Microsoft SDKs\Windows\v6.0A\\lib\gdi32.lib:

1>   Searching C:\Program Files\Microsoft SDKs\Windows\v6.0A\\lib\uuid.lib:


윗 예에서 uafxcwd.lib를 링크 할 때,링크에러가 났고,에러를 유발한 유력한 용의자는 uuid.lib입니다.왜냐면,계속 다른 애들은 디폴트 경로에서 링크되는데 uuid.lib sdk에서 링크 되었고, MFC에서 new를 재정의 하기 때문에,이전에 new가 정의되어 있는 파일이 링크되면 안됩니다.여기서 “stdafx.h”파일을 추가 하는 것을 잊었구나 하는 생각이 듭니다.


/verbose옵션을 써보지 않으신 분들은 한번 넣고 컴파일을 해보시면 쓰잘떼기 없는 정보까지 주르륵 나와서 놀라실 껍니다.여러가지 링킹 타임에 하는 작업 정보를 자세히 알려주는 것을 알 수 있습니다.윗예의 :lib처럼 뒷부분에 세부 옵션을 붙여 보기 좋게 정보를 추출하는 작업이 익숙해 지면 일반적인 컴파일시 정보를 잘 제공해주지 않는 링킹 타임시 발생하는 에러에 정보를 얻어 디버깅 작업 시간을 단축 시킬 수 있습니다.

'scrap' 카테고리의 다른 글

명령어6  (0) 2010.03.18
C++ Project Templete Create  (0) 2010.03.18
SVN 사이트  (0) 2010.03.18
Visual Studio 단축키  (0) 2010.03.18
증분링크  (0) 2010.03.18

1. http://www.assembla.com/
이곳은 가입해보니 무료 사용자는 소스를 오픈해야만 하더군요.
바로 다른 곳을 알아보았습니다.

2. http://unfuddle.com/
소스를 오픈하지 않아도 된다길래
잽싸게 가입하고 소스 올리고,
친구를 프로젝트 팀원으로 등록하려고 보니..
무료 이용자는 팀원을 2명까지만 등록할 수 있네요...

3. http://ffhosting.net/
여기는 국내 사이트입니다.
무료 계정을 신청한 사람이 svn을 신청하면
세팅해 주고 사용할 수 있게 해준다고 합니다.
그런데 다른 사이트들은 프로젝트 관리 페이지를 제공하는데
(인원, 비용, task, bug tracking 등)
이곳은 그냥 서버만 제공하는것 같네요.

4. http://www.xp-dev.com/
그래서 다시 검색하다가 이곳을 알아냈습니다.
여러명 함께 사용할수 있고 기본 용량 500MB에
앞서 말했듯이 프로젝트 관리 페이지와 토론방, 게시판 등을 사용할 수 있네요.
프로젝트는 공개/비공개를 선택할 수 있고...

SVN 으로 소스 관리하시려는 분들은 참고하세요~

'scrap' 카테고리의 다른 글

C++ Project Templete Create  (0) 2010.03.18
LinkError 추적하기  (0) 2010.03.18
Visual Studio 단축키  (0) 2010.03.18
증분링크  (0) 2010.03.18
윈도우 가상 드라이버 생성  (0) 2010.03.18

Visual Studio .NET 단축키

  • 웹사이트 이름을 적고 링크를 걸어 보세요.

    [출처] Visual Studio 단축키 활용하기 (HGC 홍익대학교 게임학부 클라이언트) |작성자 돌돌이.



  • Ctrl + F : 찾기
    Ctrl + Shift + F : 파일에서 찾기
    Ctrl + Space : NameSpace
    Ctrl + Shift + Space : Parameter
    Home : 커서가 위치한 줄의 코드 시작 위치로
    End : 커서가 위치한 줄의 코드 끝 위치로
    Shift + Home : 커서가 위치한 줄 모두 블록
    Shift + End : 커서가 위치한 줄 모두 블록
    Shift + ← or → or ↑ or ↓ : 블록 잡기
    드래그 + Alt : 현재 커서 위치부터 움직인 커서 위치까지 블록
    Ctrl + ←, → : 구분단위로 커서 이동
    Ctrl + Shift + ← or → : 구분단위로 블록
    Ctrl + M, L : 전체 + 버튼으로 만들기
    Ctrl + M, M : 커서 위치가 속한 곳을 + 버튼으로 만들기
    Ctrl + M, L : 선택된 곳을 +버튼으로 만들기
    Shift + Delete : 커서가 위치한 줄 삭제
    Ctrl + L : 커서가 위치한 줄 삭제, 선택된 줄단위로 삭제
    Ctrl + K, C : 선택 영역 주석 달기
    Ctrl + K, U : 선택 영역 주석 없애기
     
    F7 : 빌드
    Ctrl + Alt + F7 : 전체 다시 빌드
    F5 : 빌드 + 실행
    Ctrl + F5 : 빌드 없이 실행
    F9 : 브레이크 포인트 설정
    F10 : 줄단위 실행
    F11 : 코드 단위 실행
    F12 : 정의로 이동
    Ctrl + '-'키 : 이전 커서 위치로
    Ctrl + Shift + '-'키 : 다음 커서 위치로
    Ctrl + F2 : 커서가 위치한 줄에 책갈피 설정
    F2 : 다음 설정된 책갈피로 커서 이동
    Ctrl + Shift + F2 : 설정된 책갈피 모두 삭제
    Ctrl + F10 : 커서 위치까지 실행
    Alt + F8 : 선택 영역 코드 탭 정리하기
     
    마우스 우클릭 - Find All Refrence : 모든참조 찾기
    Alt + P + P : 프로젝트 속성

     


    편집 관련 단축키

    편집 관련 단축키들은 익혀두면 다른 문서를 작성 할때도 많이 도움이 될 것이다.

    문서 편집 관련 단축키들은 사용하면 사용할 수록 코딩 속도가 빨라진다.



    Ctrl + F : 찾기

    중요도 : ★★★☆☆

    활용 : 특정 클래스, 함수, 변수 등을 검색한다.





    Ctrl + Shift + F : 파일에서 찾기

    중요도 : ★☆☆☆☆

    활용 : 특정 클래스, 함수, 변수 등을 검색한다. 현제 프로젝트가 아닌 파일에서도 찾을 수 있다.





    Ctrl + Space : NameSpace

    중요도 : ★★★★★

    활용 : 현재 접근 가능한 클래스명, 함수명, DEFINE문 등의 목록을 보여준다.

             코드를 치는 도중 Ctrl + Space를 누르면 이전에 선언된 것과 

             가까운 목록을 보여주며 선택을 함으로써 쉽게 완성이 가능하다.

             목록이 하나뿐이라면 그것으로 자동 완성 해준다.





    Ctrl + Shift + Space : Parameter

    중요도 : ★★★★★

    활용 : 커서가 클래스명의 뒤에 있을 때 접근가능한 변수, 함수 목록을 보여준다.

             코드를 치는 도중 Ctrl + Shift + Space를 누르면 이전에 선언된 것과

             가까운 목록을 보여주며 선택을 함으로써 쉽게 완성이 가능하다.

             목록이 하나뿐이라면 그것으로 자동 완성 해준다.





    Home : 커서가 위치한 줄의 코드 시작 위치로

    중요도 : ★★★★★

    활용 : 커서의 위치와 관계없이 해당 줄의 코드 시작위치로 커서를 옮긴다.

             블록을 잡기 위해서, 커서의 빠른 이동 등에 많이 사용된다.





    End : 커서가 위치한 줄의 코드 끝 위치로

    중요도 : ★★★★★

    활용 : 커서의 위치와 관계없이 해당 줄의 코드 마지막위치로 커서를 옮긴다.





    Shift + Home : 커서가 위치한 줄 모두 블록

    Shift + End : 커서가 위치한 줄 모두 블록

    중요도 : ★★★★★

    활용 : 커서 위치가 가장 앞에 있다면 Shift + End를 이용해 그 줄을 블록하고 

             커서 위치가 가장 뒤에 있다면 Shift + Home를 이용해 그 줄을 블록한다.





    Shift + ← or → or ↑ or ↓ : 블록 잡기

    중요도 : ★★★★☆

    활용 : 여러 줄을 블록할 때 많이 사용한다.





    드래그 + Alt : 현재 커서 위치부터 움직인 커서 위치까지 블록

    중요도 : ★★★★☆

    활용 : 마우스 드래그 중 Alt를 누르면 드래그하는 영역을 사각형으로 봤을 때 그 영역을 블록하게 된다.

             특정 부분을 선택하고 싶거나, 탭을 먹이고 싶을 때 많이 사용된다.





    Ctrl + ←, → : 구분단위로 커서 이동

    중요도 : ★☆☆☆☆

    활용 : 현재 줄에서 커서를 좌우로 이동할 때 변수, 공백, 탭, 등의 구분단위로 이동하게된다.

             보다 빠른 커서위치를 조정하고, 블록할 때 사용된다.





    Ctrl + Shift + ← or → : 구분단위로 블록

    중요도 : ★☆☆☆☆

    활용 : 현재 줄에서 블록을 할 때 변수, 공백, 탭 등의 구분단위로 블록영역을 설정한다.

             보다 빠르게 블록 영역을 설정할 때 편리하다.





    Ctrl + M, L : 전체 + 버튼으로 만들기

    중요도 : ★★★☆☆

    활용 : 현재 소스 전체를 {}영역 별로 +버튼으로 만들어준다.

             +버튼은 소스가 삭제되는 것은아니라 감춰두는 것으로 볼 수 있다.

             소스가 길어 함수 정의나 클래스 정의 부분을 빨리 찾고 싶을 때 많이 사용된다.





    Ctrl + M, M : 커서 위치가 속한 곳을 + 버튼으로 만들기

    중요도 : ★★☆☆☆

    활용 : 커서의 위치를 {}단위로 판단하여 커서가 속한 곳을 +버튼으로 만든다.





    Ctrl + M, L : 선택된 곳을 +버튼으로 만들기

    중요도 : ★★☆☆☆

    활용 : 블록을 선택된 영역을 +버튼으로 만든다.





    Shift + Delete : 커서가 위치한 줄 삭제

    중요도 : ★★★★☆

    활용 : 커서가 위치한 줄을 삭제한다.

             빠르게 현재 줄을 삭제할 때 많이 활용된다.





    Ctrl + L : 커서가 위치한 줄 삭제, 선택된 줄단위로 삭제

    중요도 : ★★★★☆

    활용 : 위 단축키와 비슷하지만 영역을 선택했을 때 여러줄을 줄단위로 삭제 한다.





    Ctrl + K, C : 선택 영역 주석 달기

    중요도 : ★★★★☆

    활용 : 선택 영역의 주석을 한 단계씩 추가한다.





    Ctrl + K, U : 선택 영역 주석 없애기

    중요도 : ★★★★☆

    활용 : 선택 영역을 주석을 한 단계씩 감소시킨다.






    Alt + F8 : 선택 영역 코드 탭 정리하기

    중요도 : ★★★★☆

    활용 : 선택한 영역의 코드들의 탭이 뒤죽박죽일 때 사용하면 편리하다.










    디버깅 관련 단축키


    F7 : 빌드

    중요도 : ★★★☆☆

    활용 : 이번 빌드 상태와 비교하여 수정된 소스에 대해 다시 빌드한다.





    Ctrl + Alt + F7 : 전체 다시 빌드

    중요도 : ★★★☆☆

    활용 : 현재 솔루션 전체를 다시 빌드한다. 링크가 꼬엿을 때 외엔 잘 사용하지 않는다.





    F5 : 빌드 + 실행

    중요도 : ★★★★★

    활용 : F7을 누른후 실행한 결과와 같다.





    Ctrl + F5 : 빌드 없이 실행

    중요도 : ★☆☆☆☆

    활용 : 최근에 빌드된 상태의 실행 파일을 실행시킨다.

             소스 수정없이 다시 실행 시키고 싶을 때 빌드 시간 없이 실행 하므로 빠르다





    F9 : 브레이크 포인트 설정

    중요도 : ★★★★★

    활용 : 현재 커서가 위치한 줄에 중단점을 설정한다.

             중단점이 걸리면 디버그시 해당 코드를 실행하기전에 중지되어 사용자에게 코드 위치를 보여준다.





    F10 : 줄단위 실행

    중요도 : ★★★★★

    활용 : 디버깅 모드에서 현재 디버깅하고있는 소스의 줄단위로 진행 시킨다.





    F11 : 코드 단위 실행

    중요도 : ★★★★★

    활용 : 디버깅 모드에서 현재 진행중인 커서위치의 코드를 실행한다.

             커서위치의 코드내에 함수가 있다면 그 함수의 내부로 들어가게 된다.





    F12 : 정의로 이동

    중요도 : ★★★★★

    활용 : 변수, 함수, 클래스 등의 선언부로 이동한다.

             눈에 보이는 변수, 함수 등의 정체를 확인하는데 많이 사용된다.





    Ctrl + '-'키 : 이전 커서 위치로

    중요도 : ★★★★★

    활용 : 이전 커서위치로 이동하게 된다.

             보통 F12로 변수를 탐색한후, 다시 돌아오는데 많이 사용한다.





    Ctrl + Shift + '-'키 : 다음 커서 위치로

    중요도 : ★☆☆☆☆

    활용 : 위의 단축키와 반대 되는 개념이다.





    Ctrl + F2 : 커서가 위치한 줄에 책갈피 설정

    중요도 : ★★★☆☆

    활용 : 현재 문서에서 커서가 위치한 줄에 책갈피를 설정한다.

             책갈피는 관심있는 코드를 메모해놓고 쉽게 접근하기 위해 사용한다.





    F2 : 다음 설정된 책갈피로 커서 이동

    중요도 : ★★★☆☆

    활용 : 현재 문서에서 설정된 책갈피가 있을 때 순차적으로 책갈피를 탐색한다.





    Ctrl + Shift + F2 : 설정된 책갈피 모두 삭제

    중요도 : ★★★☆☆

    활용 : 현재 문서에 설정되어 있는 책갈피를 모두 삭제한다.





    Ctrl + F10 : 커서 위치까지 실행

    중요도 : ★★☆☆☆

    활용 : 현재 커서가 위치한 곳까지 실행하게 된다.

             편집상태라면 빌드 + 커서 위치까지 실행된다.

             한손으로 누르기 힘든 단축키라 우클릭 메뉴를 이용해도 좋다.








    기타


    마우스 우클릭 - Find All Refrence : 모든참조 찾기

    중요도 : ★★★★☆

    활용 : 현재 커서가 위치한곳의 변수나 함수등이 사용된 곳을 프로잭트에서 모두 찾아 표시한다.

             LifeCycle 을 알아보는데도 좋다.





    Alt + P + P : 프로젝트 속성

     

    중요도 : ★☆☆☆☆


    활용 : 프로젝트의 속성을 본다. 프로젝트 속성을 보는일은 많이 없으므로 큰 활용도는 없다.



    'scrap' 카테고리의 다른 글

    LinkError 추적하기  (0) 2010.03.18
    SVN 사이트  (0) 2010.03.18
    증분링크  (0) 2010.03.18
    윈도우 가상 드라이버 생성  (0) 2010.03.18
    Gentoo Linux 설치  (0) 2010.03.18

    증분링크(incremental link)는 바이너리를 가능한 빠르게 링크하고자 함수 호출시 직접적인 주소를 참조하지 않고 별도의 테이블(ILT, 증분링크테이블)로 관리를 하여 함수가 수정되어 크기가 변하여도 모든 CALL 명령을 찾아 수정을 가하는게 아니고 테이블만 변경할수 있도록 하여 링크 속도를 높인다.

    ILT 테이블 예
    @ILT+0(_wmain):
    00401005 jmp wmain(401070h)
    @ILT+5 (??_GCResString@@UAEPAXI@Z)
    0040100A jmp CResString::'scalar deleting destructor' (401B40h)

    증분링크시 추가적인 패딩데이타가 실행파일에 추가되어 용량이 커진다.

    /INCREMENTAL:yes 또는 no로 설정할수 있고 이와 관련된 정보는 .ilk에 저장되어 사용된다.

    디버그 모드에서 실행중 수정하면서 진행하려면 증분링크로 빌드되어야 한다. (VS에서는 /DEBUG 시 자동적으로 /INCREMENTAL 이 지정된다.)

    그외에 /OPT:REF /OPT:ICF 를 선택하면 증분링크는 무시되고 비증분링크를 수행한다.

    API Hooking시 증분링크에 대한 체크가 필요하다.

    // 증분 링크 체크
    // Microsoft Visual C++은 실행중에도 코드를 수정할 수 있게끔
    // 증분 링크를 사용하여 함수의 주소가 실제 함수를 가리키지 않고, 실제 함수로 jmp 하는 명령의 주소로 되어 있다.
    // 참고: System DLL일 경우에 무시
    if ((DWORD)fnApi < 0x80000000 && *(PBYTE)fnApi == 0xE9)
    {
      fnApi = (PROC)((int)(fnApi) + (*(int *)((PBYTE)fnApi+1)) + 5);
    }


    'scrap' 카테고리의 다른 글

    SVN 사이트  (0) 2010.03.18
    Visual Studio 단축키  (0) 2010.03.18
    윈도우 가상 드라이버 생성  (0) 2010.03.18
    Gentoo Linux 설치  (0) 2010.03.18
    WSS / MOSS Sp2 설치  (1) 2010.03.18

    + Recent posts