여러 가지 이유로 Intel 가상화 기술(Virtualization Technology)을 직접 활용한 시스템 소프트웨어를 구현한 이야기를 예전에 잠시 했었습니다. Shadow-box라고 부르고 있는데... 그 녀석(?!)으로 인해 영혼까지 탈탈 털리고 있는 중입니다. ^^;;; 2015년에 처음 개발을 시작했으니까 올해가 5년 차인데, 뮤택스와 스핀락 관련 이야기(https://kkamagui.tistory.com/925)에서 잠깐 소개를 하기도 했죠.

경량 가상화 기술을 이용한 영역(World) 분리

처음 가상화 기술로 영역을 분리하고 나니 잘 되는 듯 하지만 실제로는 잘 안 되는(?!) 상황이 많이 발생했는데요, 이러한 일들이 커널이 변경되어 새로운 기능이 추가되거나 단말이 바뀔 때마다 나와서... 정말 탈탈 털리고 있다는 표현이 맞는 것 같네요. 정말 멜트다운(Meltdown) 때문에 PTI(Page Table Isolation)이 커널에 들어갔을 때는 죽을 맛이었는데... 어쨌거나 큰 산을 넘고 또 넘어서 지금은 많이 안정화가 되었습니다. 물론... 새로운 문제가 나오기 전까지 안정적인 거지만요. ^^;;;

이번에 단말을 바꾸면서 여러가지 시험을 진행하고 있었는데요, 특정 단말에서만 한 20분을 못 넘기고 멈추는 문제가 발생했습니다. 이 문제 때문에 며칠 밤을 새웠는데요, 딱히 의심되는 부분이 없어서 계속 반복 실행하면서 로그를 확인했는데 별다른 로그가 없이 시스템이 정지했습니다. 사실 Shadow-box에 문제가 있거나 페이지 테이블 맵핑에 문제가 있으면 이런 현상이 생겼던 경험이 있어서 페이지 테이블 쪽을 의심하고 있던 찰나... 인터럽트 발생 횟수를 아래처럼 살펴보다 보니 NMI(Non-Maskable Interrupt)가 꽤 많이 발생한 것이 보이더라구요.  

$ cat /proc/interrupts
            CPU0       CPU1       CPU2       CPU3       CPU4       CPU5       CPU6       CPU7       CPU8       CPU9       CPU10      CPU11      CPU12      CPU13      CPU14      CPU15      
 NMI:         51        179        778         16        241         33         77         90         47        127        408        136        268         62        192        219   Non-maskable interrupts

NMI는 마스킹, 즉 비활성화가 불가능해서 언제 어디서건 발생할 수 있기 때문에 핸들러가 반드시 있어야 합니다. 당연히 게스트(Guest), 즉 리눅스가 동작하는 일반 영역에서 발생하면 커널의 핸들러가 불려서 처리가 되니 문제가 없을 거라 생각했는데... 문득 호스트(Host), 즉 커널 보호 기술이 동작하고 있는 영역에서 발생하면 문제가 생길 것 같은 느낌이 들었습니다. 아니나 다를까, 실제로 인터럽트 핸들러를 생성해서 로그를 찍어보니 아주 간간히 NMI 인터럽트가 호스트에서도 발생하고 있었습니다. 그리고 그때마다 게스트의 NMI 핸들러를 불러서 처리를 하고 있더라구요. 아아... 이러면 안 되는데... ㅠ^ㅠ

호스트는 리눅스 커널의 기능을 최소로 활용하기 때문에 NMI 핸들러를 실행할 만큼 자원이나 호출 가능한 함수가 충분치 않거든요. 그래서 이번 기회에 인터럽트 핸들러를 호스트용 하나 더 만들고 게스트와 분리시켜줬습니다. 호스트의 인터럽트 핸들러는 아무것도 할 필요가 없기 때문에 로그만 찍는 더미(Dummy) 핸들로로 모두 연결했죠. 그랬더니 새로운 단말에서도 다시 안정적으로 동작을 하기 시작했습니다. >ㅁ<)/~ 로그를 보니 거의 몇 분 단위로 NMI 인터럽트가 발생하고 있더라구요.

$> sudo journalctl -f | grep shadow-box
 8월 03 00:22:11 machine kernel: shadow-box: VM [3] INT NMI callback
 8월 03 00:24:18 machine kernel: shadow-box: VM [5] INT NMI callback
 8월 03 00:26:02 machine kernel: shadow-box: VM [8] INT NMI callback
 8월 03 00:26:32 machine kernel: shadow-box: VM [0] INT NMI callback
 8월 03 00:27:52 machine kernel: shadow-box: VM [13] INT NMI callback
 8월 03 00:29:45 machine kernel: shadow-box: VM [6] INT NMI callback
 8월 03 00:31:21 machine kernel: shadow-box: VM [7] INT NMI callback
 8월 03 00:36:26 machine kernel: shadow-box: VM [9] INT NMI callback
 8월 03 00:37:36 machine kernel: shadow-box: VM [11] INT NMI callback
 8월 03 00:42:54 machine kernel: shadow-box: VM [1] INT NMI callback
 8월 03 00:44:30 machine kernel: shadow-box: VM [14] INT NMI callback
 8월 03 00:48:18 machine kernel: shadow-box: VM [15] INT NMI callback
 8월 03 00:51:03 machine kernel: shadow-box: VM [4] INT NMI callback
 8월 03 00:54:26 machine kernel: shadow-box: VM [12] INT NMI callback
 8월 03 01:12:17 machine kernel: shadow-box: VM [10] INT NMI callback
 8월 03 01:59:58 machine kernel: shadow-box: VM [2] INT NMI callback

어휴... 진땀을 뺐네요. 자칫 잘못하면 엄청 길어질 뻔했는데, 운이 좋아서 다행입니다.

그럼 좋은 밤 보내세요. ^^

ps) CPU의 인터럽트 핸들러나 실제 핸들링 과정이 궁금하신 분은 64비트 멀티코어 OS 원리와 구조*(http://www.yes24.com/Product/Goods/65061299)를 참고하시면 좋을 것 같습니다.

 

64비트 멀티코어 원리와 구조가 나온지 약 3년이 지났습니다. 그동안 QnA 사이트를 운영하면서 가장 많이 받았던 질문이 개발환경 설정에 대한 글이었는데요, 아무래도 cygwin 버전이 올라가다보니 책에 있는 빌드방법으로는 제대로 빌드가 되지 않더라구요(지금도 개발환경에 대한 질문이 계속 올라온다는...). ㅠㅠ 그래도 많은 분들이 도와주셔서 어찌어찌 성공하신 분들도 있지만... 사실 책임은 저한테 있는지라 언젠가는 해결해야 겠다고 생각했습니다.

<64비트 멀티코어 원리와 구조 - 출처 yes24>

그래서~!!! 오늘 애기를 빡시게 놀게한다음 일찍 재우고 다시 개발환경을 만드는 중입니다. 그래서 내용도 업데이트하고 이번에는 가상머신으로 만들어서 다운받아 바로 쓸 수 있도록 만들 생각입니다. @0@)-b 이렇게 하면 빌드에 문제가 생겨도 가상머신을 다운받아 실행하면 되니 문제가 없을 것 같더군요. ^^;;;

크로스 컴파일러를 만드는게 시간이 많이 걸리는지라... 지금 시작하면 언제 끝날지 잘 모르겠네요. ㅠㅠ 그래도 이번에 확실히 해서 큰 포부를 가지고 OS 개발을 시작하셨다가... 개발 환경 설정 때문에 좌절하시는 일이 없도록 잘 해보겠습니다. @0@)/~

그럼 좋은 밤 되세요 >ㅁ<)-b

ps1) 아침에는 개발 환경 설정을 업데이트 할 수 있으면 좋겠네요 ㅠㅠ

ps2) Yes24 사이트에서는 책이 품절로 나오는군요. ' ')a... 교보문고에 가시면 아직 구할 수 있습니다. ^^

64비트 멀티코어 OS 원리와 구조 세트가 출간된지 3년이 다 되어갑니다. 책에 대한 QnA 사이트가 필요해서 책 출간과 동시에 mint64os.pe.kr 사이트도 운영 중인데요, 지금까지 약 300개의 QnA가 달렸습니다. @0@)/~ (그중에 오탈자에 대한 문의도 다수 있다는 건 함정... 쿨럭..;;;)

<출처 - yes24.com>

질문에 대해서 답변을 달다보면 가끔 통찰력이 느껴지는 질문도 있는데요, 이런 질문들은 혼자보기가 아깝더라구요. ^^;;; 그래서 정리해서 공유하는게 어떨까하는 생각을 했습니다. 시간이 나는대로 틈틈이 정리해서 올려볼 예정이니 기대해주세요 >ㅁ<)/~

그럼 좋은 하루 되세요 ^^

"64비트 멀티코어 OS 원리와 구조"가 출간된지 벌써 1년이 다되었습니다. ^^)-b 그동안 MINT64 OS 개발과 관련해서 많은 질답이 오고 갔는데요, 그중에서 빼 놓을 수 없는 것이 바로 "개발 환경 설정"과 관련된 내용입니다. ㅠㅠ 실제로 개발 환경 설정때문에 많은 분들이 고생을 하고 계신데요, 이 문제로 고민하시던 Ethobis님께서 해결책을 내놓으셨습니다(Ethobis님 감사합니다. ㅠㅠ).


Ethobis님께서 사용하신 방법은 Cygwin을 기본으로 설치하고 난 뒤 부록 CD에 있는 개발환경을 그대로 복사하는 방법인데요, Cross Compiler를 만드는 복잡한 단계를 거치지 않아도 되기 때문에 괜찮은 것 같습니다. ^^


부록 CD를 다운 받는 곳과 Ethobis님의 글은 아래에서 보실 수 있습니다. ;)


    부록 CD : http://jsandroidapp.cafe24.com/xe/220

    Ethobis님의 글 : http://ethobis.tistory.com/63


그럼 즐거운 OS 프로그래밍하세요 :)


ps) 좋은 팁을 알려주신 Ethobis님께 감사의 말씀을 전합니다. ^^

<64비트 멀티코어 OS 원리와 구조>


제가 오랜시간을 걸쳐 정리한 책, 64비트 멀티코어 OS 원리와 구조가 "2012년 대한민국학술원 우수학술도서"에 선정되었습니다. 이런 영광이... 제게도 이런 날이 오는군요. ㅠㅠ)-b 우수 학술 도서 목록은 http://www.nas.go.kr/info/notice/view.jsp?NP_Code=10000043&NP_DataCode=20000014&NGB_Code=10001430에서 살펴보실 수 있습니다. ^^


그동안 64비트 멀티코어 OS 원리와 구조를 구매해주신 많은 분들께 감사드리며, 우수학술도서로 선정될 수 있도록 힘써주신 한빛미디어의 한동훈님께 감사드립니다. 그리고 책이 나올 수 있도록 도와주시고 응원해주신 많은 분들께도 감사의 말씀을 드립니다. 앞으로 책이 많이 나가서 얼른 2쇄 찍고 부끄러운 오탈자를 정리할 수 있으면 좋겠네요. ㅠㅠ)-b


앞으로 더욱 열심히 하는 kkamagui가 되겠습니다. ^^)-b

그럼 좋은 밤(?) 되세요 ;)


굵게 표시된 부분이 오타가 수정된 부분입니다.


==== 1권의 오탈자 내용 ====

*. 79 Page, 아래에서 5 번째 줄

보호 모드는 IA-32e 모드로 전환하려면 공식적으로 거쳐야 하는 모드로, 32비트 윈도우나 리눅스 OS가 동작하는 기본 모드입니다.


*. 80 Page, 위에서 6 번째 IA-3e 모드를 IA-32e 모드로 수정

IA-32e 모드


*. 80 Page, 아래에서 5 번째줄

리얼 모드에서 전환할 수 있는 모드는 공식적으로 보호 모드뿐 이며, 보호 모드에서는 가상 8086 모드나 IA-32e 모드, 다시 리얼 모드로 전환할 수 있습니다. 시스템 관리 모드는 모든 모드에서 진입할 수 있고, 처리가 끝나 이전의 운영 모드로 복귀하거나 리셋을 통해 리얼 모드로 진입할 수 있습니다.


*. 80 Page, 아래에서 3 번째 줄

화살표가 연결되지 않은 리얼 모드에서 IA-32e 모드로 전환하는 것은 불가능하며, 무리하게 시도하면 리셋이나 예외가 발생할 수있습니다(실제 편법을 사용하면 가능하긴 하지만 여기서는 다루지 않습니다).


*. 83 Page, [그림 3-3]에서 128비트 XMM 레지스터(16개), 64비트 RIP, 64비트 RFLAGS, CR8 레지스터 부분 수정됨

[그림 3-3].PNG


*. 85 Page의 "여기서 잠깐"의 시작에서 6번째 줄

곱셈 명령은 AX와 오퍼랜드를 곱한 후, 그 결과를 DX:AX나 혹은 AX에 저장하도록 설계되었습니다.


*. 87 Page 아래에서 5번째 줄부터...

그렇다면 어떻게 해야 할까요? 프로세서 제조사에서는 이런 경우를 대비하여 무조건 분기 명령어(jmp)에 예외를 두었습니다.

즉, 무조건 분기 명령어의 오퍼랜드의 크기는 기본 64비트로 하여 전체 어드레스 범위에서 이동이 가능하도록 한 것입니다.

[그림 3-5]는 RIP 상대 어드레스를 사용하여 표현 가능한 어드레스 영역과 무조건 분기 명령어를 사용해서 접근할 수 있는 영역에 대해

나타낸 것입니다.


*. 88 Page [그림 3-5]

           [그림 3-5].png


*. 113 Page 아래에서 8번째 줄

그 위쪽에서 두 파일은 a.c와 b.c로부터 생성되는 것을 알 수 있습니다.


*. 141 Page 위에서 6번째 줄, 154 Page 아래서 5번째 줄, 2861 Page 위에서 7번째 줄, 2872 Page 맨 밑줄

xor byte [ HEADNUMBER ], 0x01 ; 헤드 번호를 0x01과 XOR 하여 토글(0->1, 1->0)


*. 142 Page, 아래서 3번째줄

x86 프로세서의 스택은 [그림 5-3]과 같이 데이터가 삽입될 때마다 스택의 상위(Top)를 나타내는 스택 포인터 레지스터(SP)가 낮은 어드레스(0x00에 가까운 어드레스)로 이동합니다.


*. 143 Page, 밑에서 10째줄

또한 스택은 넉넉한 것이 좋으므로 스택 포인터 레지스터(SP)와 베이스 포인터 레지스터(BP)를 0xFFFF로 설정하여, 스택 영역의 크기를 세그먼트의 최대 크기로 지정하겠습니다.


*.149 Page, 아래에서 13번째 줄

        ret 12                   ; 호출한 함수로 복귀한 후, 스택에 삽입된 파라미터 3개를 제거(3*4) "ret" "add esp, 12"와 같은 역할

        ^^^^^^

            ret 수행 후 스택 포인터(SP)를 12만큼 더함. 보호모드 코드이므로

            레지스터의 기본 크기 및 스택의 기본 크기가 32비트(4바이트)이기 때문에 4*3 = 12만큼 더함


*.151 Page, 위에서 15번째 줄

        ret 4                     ; 호출한 함수로 복위한 후, 스택에 삽입된 파라미터 1개를 제거(1*4) "ret" "add esp, 4"와 같은 역할

        ^^^^^^^

             ret 수행 후 스택 포인터(SP)를 4만큼 더함. 보호 모드 코드이므로

             레지스터의 기본 크기와 스택의 기본 크기가 32비트(4바이트)이기 때문에 4*1 = 4만큼 더함


*. 161 Page, 아래서 5번째줄 Code

; 512 - ( $ - $$ ) % 512 : 현재부터 어드레스 512까지


*. 213 Page, 가장 아래번째 줄

보호 모드 엔트리 포인트(EntryPoint.s) 코드에서 최초로 실행되는 C 코드입니다.


*. 251 Page, [그림 9-2] 페이지 디렉터리 엔트리 부분에서 PS1을 PS로 수정

[그림 9-2].PNG


*. 261 Page, 위에서 4번째 줄

kSetPageEntryData( &( pstPML4TEntry[ 0 ] ), 0x00, 0x101000, PAGE_FLAGS_DEFAULT, 0 );


*. 263 Page, [그림 9-5]의 XMSE를 SMXE로 수정


[그림 9-5].PNG


*. 266 Page, 소스 코드에서 위에서 10째줄

// 1 비트 P, RW, US, PWT, PCD, A, D, PS, G, 3 비트 Avail, 1 비트 PAT, 8 비트 Reserved,


*. 283 Page, [표 10-2] IA32_EFER 레지스터의 비트 구성에서 7번째 줄 LMA 항목

LMA 읽기 전용 -1로 설정되면 프로세서 모드가 IA-32e 모드(호환 모드 또는 64비트 모드)임을 나타내며, 0으로 설정되면 프로세서 모드가 기타 모드임을 나타냄


*.283 Page, 밑에서 10째줄

[표 10-2]에서 보는 것과 같이 IA-32e 모드 활성화 여부는 비트 8에 위치하는 LME 비트와 관계가 있고 이 비트를 1로 설정하면 IA-32e 모드를 활성화할 수 있습니다.


*.288 Page [예제 10-2] 위에서 1째줄

#ifndef __MODESWITCH_H__

#define __MODESWITCH_H__


*. 333 Page 아래쪽과 351 Page 가운데 부분, 482 Page 윗부분

BOOL kChangeKeyboardLED( BOOL bCapsLockOn, BOOL bNumLockOn, BOOL bScrollLockOn )

{

    int i, j;


    // 키보드에 LED 변경 커맨드 전송하고 커맨드가 처리될 때까지 대기

    for( i = 0 ; i < 0xFFFF ; i++ )

    {

        // 입력 버퍼(포트 0x60)가 비었으면 커맨드 전송 가능

        if( kIsInputBufferFull() == FALSE )

        {

            break;

        }

    }

...   생략 ...


*. 334 Page 위에서 3번째 줄

// 입력 버퍼(포트 0x60)로 LED 상태 편경 커맨드(0xED) 전송

kOutPortByte( 0x60, 0xED );

... 생략 ...


*. 341 Page 위에서 15번째 줄, 357 Page 아래에서 5번째 줄

BOOL kIsUseCombinedCode( BYTE bScanCode )


*. 341 Page, 위에서 18번째 줄, 357 Page, 아래에서 2번째 줄

BOOL bUseCombinedKey = FALSE;


*. 343 Page 아래쪽359 Page 가운데 부분

void UpdateCombinationKeyStatusAndLED( BYTE bScanCode )

{

    BOOL bDown;

    BYTE bDownScanCode;

    BOOL bLEDStatusChanged = FALSE;


    // 눌림 또는 떨어짐 상태처리, 최상위 비트(비트 7)가 1이면 키가 떨어졌음을 의미하고

    // 0이면 눌림을 의미함

    if( bScanCode & 0x80 )

    {

        bDown = FALSE;

        bDownScanCode = bScanCode & 0x7F;

    }

    else

    {

        bDown = TRUE;

        bDownScanCode = bScanCode;

    }


*. p.363 페이지 (02.Kernel64/Source/Keyboard.h)의 Down을 On으로 변경
// 키보드의 상태를 관리하는 자료구조
typedef struct kKeyboardManagerStruct
{
    // 조합 키 정보
    BOOL bShiftDown;
    BOOL bCapsLockOn;
    BOOL bNumLockOn;
    BOOL bScrollLockOn;
    
    // 확장 키를 처리하기 위한 정보
    BOOL bExtendedCodeIn;
    int iSkipCountForPause;
} KEYBOARDMANAGER;


*. 365 Page, 아래에서 12번째 줄

BOOL kIsUseCombinedCode( BYTE bScanCode );


*. 365 Page, 아래에서 17번째줄 변수 선언 부분 굵게 처리

void Main( void )

{

    char vcTemp[ 2 ] = {0, };

    BYTE bFlags;

    BYTE bTemp;

    int i = 0;


    ... 생략 ...



*. 383 Page의 [그림 12-7]에서 16~31 비트의 값(크기를 기준 주소로 수정)

그림 12-7.PNG


*. 386 Page, 위에서 21번째 줄 30번째 줄

#define GDT_FLAGS_LOWER_TSS ( GDT_FLAGS_LOWER_DPL0 | GDT_FLAGS_LOWER_P

#define GDT_FLAGS_UPPER_TSS ( GDT_FLAGS_UPPER_G )


*. 428 Page 아래에서 18번째 줄, 436 Page 아래에서 3번째 줄, 600 Page 아래에서 9번째 줄, 606 Page 위에서 7번째 줄

%macro KLOADCONTEXT 0      ; 파라미터를 전달받지 않는 KLOADCONTEXT 매크로 정의


*. 483 Page, 위에서 10번째 줄, 굵게 표시

// 키를 저장하는 큐와 버퍼 정의

static QUEUE gs_stKeyQueue;

static KEYDATA gs_vsKeyQueueBuffer[ KEY_MAXQUEUECOUNT ];


*. 492 Page의 위쪽

사실 14장은 앞 장과 비교해서 변한 것이 거의 없습니다.


*. 498 Page의 "GCC 헤더 파일에 정의된 가변 인자 매크로와 리스트"의 위쪽 문단

각 매크로와 데이터 타입이 어떻게 정의되어 있는지 코드를 직접 확인해 보겠습니다.


*. 609 Page, 첫 번째 줄  굵게 표시

{ "createtask", "Create Task", kCreateTestTask },


*. 620 Page의 [그림 18-3]

그림 18-3.png


*. 627 Page, "TCB 할당 및 해제 함수의 코드"에서 위로 2번째 줄

다음은 앞서 설명한 내용에 따라 구현한 TCB 할당 및 해제 함수의 코드입니다. ID를 처리하는 부분을 제외하고는 평이한 코드이므로

이해하는데 큰 어려움이 없을 것입니다. TCB 자료구조에 추가된 stLink 필드는 18.2.4절에서 살펴보겠습니다.


*. 660 Page의 위에서 4째줄

콘솔 화면의 주변을 돌면서 문자를 출력하는 태스크와 자신의 ID에 해당하는 위치에 바람개비를 출력하는 태스크를 작성했습니다.


*. 741 Page 위에서 7 번째 줄

태스크의 수를 제한하려면 임계 영역 진입 여부를 나타내는 플래그와 잠금 횟수를 나타내는 카운터, 그리고 임계 영역에 진입한 태스크의 ID만 있으면 처리할 수 있습니다.


*. 742 Page 아래에서 8번째 라인

만약 잠근 태스크가 해제를 요청하는 것이고 잠긴 횟수가 2 이상이면 중복으로 잠긴 것이므로 횟수만 1 감소시키고 실제로 해제하는 작업은 수행하지 않습니다.


*. 751 Page 그림 [20-4]

[그림 20-4].PNG


*. 769 Page 맨 윗 라인

콘솔 셸 파일에는 태스크를 생성하고 종료하는 태스트 때문에 killtask 커맨드의 기능이 수정되고 동기화 기능을 테스트하는 testmutex 커맨드가 추가되었습니다.


*. 791 Page의 밑에서 셋째줄

하지만 멀티코어 프로세서 환경일 경우 자식 스레드는 다른 코어에서 실행될 수 있으며, 이런 경우 태스크를 즉시 대기 리스트로 옮길 수 없습니다.


*. 815 Page의 밑에서 8째줄

[그림 21-4]의 위를 보면 콘솔 셸(태스크 ID: 0x100000000)과 유휴 태스크(태스크 ID: 0x200000001)의 태스크 플래그를 보면 최상위 바이트가 각기 0x60과 0x58로 시작하는 것을 볼 수 있습니다.


*. 825 Page [그림 22-2]

[그림 22-2].PNG


* 843 Page, 밑에서 10 째줄

또 FPU 예외 처리가 끝나면 다시 0으로 설정해서 같은 태스크가 FPU를 사용할 때 예외가 발생하지 않도록 해야 합니다.


* 876 Page, 밑에서 두번째 줄

1KB 블록 2개를 생성한 후 1KB 블록 하나를 할당해주면 남은 블록은 [그림 23-3]과 같이 1KB 블록 1개, 2KB 블록 1개, 4KB 블록 1개가 됩니다.


* 879 Page, 위에서 3번째 줄 그림 제목

[그림 23-6] 블록 크기에 맞지 않는 메모리를 할당받았을 때 할당된 메모리의 구조(4.3MB 할당)


* 933 Page 위에서 7 째줄

하지만, LBA 어드레스 모드일 때는 레지스터가 LBA 어드레스로 통합되어 섹터 번호 레지스터는 LBA 어드레스의 0비트~7비트, 실린더 LSB 레지스터는 8비트~15비트, 실린더 MSB 레지스터는 16비트~23비트, 드라이브/헤드 레지스터의 헤드 필드는 24비트~27비트를 저장합니다.


* 1049 Page, 위에서 6번째 줄 자료구조에서 아래의 굵게된 부분 추가

typedef struct kFileHandleStruct
{
    // 파일이 존재하는 디렉터리 엔트리의 오프셋
    int iDirectoryEntryOffset;
    // 파일 크기
    DWORD dwFileSize;
    // 파일의 시작 클러스터 인덱스
    DWORD dwStartClusterIndex;
    // 현재 I/O가 수행중인 클러스터의 인덱스
    DWORD dwCurrentClusterIndex;
    // 현재 클러스터의 바로 이전 클러스터의 인덱스
    DWORD dwPreviousClusterIndex;
    // 파일 포인터의 현재 위치
    DWORD dwCurrentOffset;
} FILEHANDLE;


* 1120 Page 위에서 6 째줄

// 파일 이름 삽입

kMemCpy( vcBuffer, pstentry->d_name, kStrLen( pstEntry->d_name ) );


* 1161 Page, [그림 27-5]의 가장 마지막 부분

[그림 27-5].PNG


*. 1174 Page, 위에서 11 번째 줄

iRealReadCount = MIN( gs_stRDDManager.dwTotalSectorCount -

dwLBA, iSectorCount );


*. 1174 Page, 밑에서 9 번째 줄

iRealWriteCount = MIN( gs_stRDDManager.dwTotalSectorCount -

dwLBA, iSectorCount );


*. 1186 Page, 밑에서 16 번째 줄

iRealReadCount = MIN( gs_stRDDManager.dwTotalSectorCount -

dwLBA, iSectorCount );

*. 1186 Page, 밑에서 2 번째 줄

iRealWriteCount = MIN( gs_stRDDManager.dwTotalSectorCount -

dwLBA, iSectorCount );


*. 1239 Page, 위에서 10째줄과 13째줄

// LSB 제수 래치 레지스터(포트 0x3F8)에 제수의 하위 8비트를 전송

// MSB 제수 래치 레지스터(포트 0x3F9)에 제수의 상위 8비트를 전송


*. 1246 Page, 위에서 2째줄과 5째줄

// LSB 제수 래치 레지스터(포트 0x3F8)에 제수의 하위 8비트를 전송

// MSB 제수 래치 레지스터(포트 0x3F9)에 제수의 상위 8비트를 전송


*. 1251 Page, [예제 28-3]의 소스 부분
#include "FileSystem.h" <-- Normal 글씨체로 수정
#include "SerialPort.h" <-- Bold 글씨체로 수정

*. 1280 Page, 위에서 5번째줄, 맨 앞의 "-"를 "*"로 대체하고 위의 *와 같은 레벨로 들여쓰기 수정
* BIOS의 롬 영역 중에서 0x0F0000~ 0x0FFFFF 범위 내에 존재

* 1291 Page, [그림 29-13]에서 전달할 로컬 APIC INTIN을 전달할 로컬 APIC LINTIN으로 수정, 0x000x04로 수정
[그림 29-13].PNG  
* 1399 Page, [그림 31-1]에서 오른쪽 아래에 있는 "ㅁ: 비활성화 된 부분"의 사각형을 회색으로 변경
[그림 31-1].PNG

==== 2권의 오탈자 내용 ====

*. 1528 Page, 아래에서 11번째 줄

태스크 풀을 관리하는 함수를 수정하는 방법은 33.2.2절에서 살펴보므로, 이번 절에서는 수정된 태스크 풀 자료구조만 살펴보고 넘어가겠습니다.


*. 1539 Page, 위에서 7번째 줄, 1580 Page, 아래에서 12번째 줄

// 나머지 코어에서 현재 태스크와 같은 레벨을 검사


*. 1612 Page, 아래에서 2째줄

하지만, 7부가 지나면 곧 다시 돌아오니 너무 아쉬워 할 필요는 없습니다.


*. 1655 Page, 위에서 5번째 줄

브레슨햄 직선 알고리즘을 사용한 선 그리기 함수의 코드 - 최적화 후


*. 1672 Page, 35.2.1절에서 아래로 8번째줄

하지만, 문자 정보가 비트맵으로 들어 있으므로 확대하거나 축소했을 때 문자가 깨끗하게 표시되지 않고, 굵게하거나 기울일려면 해당 스타일의 비트맵을 모두 생성해야하는 단점이 있습니다.


*.1764 Page, 아래에서 10번째줄, kDrawMouse -> kDrawCursor로 수정

kDrawCursor( &stScreenArea, pstVideoMemory, iX, iY );


*. 1882 Page, 위에서 7번째 줄

이 절에서 작성할 윈도우 매니저는 더 이상 테스트 코드가 아닌 실제 코드로서, 키보드와 마우스 데이터를 이용해 윈도우로 이벤트를 전달하는 기능과 업데이트를 수행하는 기능을 구현합니다.


*. 1946 Page, 위에서 4번째 줄

//----------------------------------------------------------------------------------------------

// 제목 표시줄 그리기

//----------------------------------------------------------------------------------------------

// 제목 표시줄을 채움

        if( bSelectedTitle == TRUE )
        {
            stTitleBarColor = WINDOW_COLOR_TITLEBARACTIVEBACKGROUND;
        }
        else
        {
                stTitleBarColor = WINDOW_COLOR_TITLEBARINACTIVEBACKGROUND;

        }


kInternalDrawRect( &stArea, ... 생략 ...)


*. 1951 Page, 위에서 6번째 줄

39장의 내용을 MINT64 OS에 추가한 뒤 make를 입력하면 Disk.img 파일이 생성됩니다.


*. 1994 Page, 위에서 6번째 줄 제목

41.1.1 Z 순서의 가장 아래에서 위로 그리는 알고리즘의 문제점


*. 1998 Page, 위에서 3번째 줄

윈도우 1은 자신의 영역에 포함된 픽셀 오프셋 5~7 부분을 비디오 메모리로 전송한 뒤 해당 영역의 비트맵을 모두 0으로 표시합니다.


*. 2027 Page, 아래에서 3번째 줄

특히 마우스 데이터를 처리하는 부분과 화면 업데이트 요청을 처리하는 부분은 조금만 수정하면 화면 업데이트 횟수를 많이 줄일 수 있기 때문에 속도에 목마른 우리에겐 아주 중요한 포인트입니다.


*. 2150 Page, 위에서 첫번째 줄

43장에서는 프로세서의 정보와 메모리 정보를 표시하는 시스템 모니터 태스크를 구현해 봤습니다. 


*. 2150 Page, 위에서 6번째 줄

44장에서는 다시 고전으로 돌아가 역사의 뒤안길로 사라졌던 콘솔 셸을 GUI 버전으로 부활시킬 것입니다.


*. 2169 Page, 위에서 7번째 줄 도움말

while( kGetKeyFromGUIKeyQueue( &stData) == FALSE)

        |---------- 그래픽 모드용 키 큐에서 데이터를 꺼내는 함수


*. 2182 Page, "44.3.2 콘솔 파일 수정"에서 아래 첫번째 줄

콘솔 파일은 그래픽 모드 지원을 위해 입출력 함수의 코드를 일부 수정하고, 그래픽 모드용 화면 버퍼와 키 큐를 추가했습니다.


*. 2309 Page 전체를 아래 내용으로 교체2309 페이지의 내용.PNG


*. 2400 Page, 아래에서 4번째 줄

MINT64 OS에는 아직까지 MSR에 읽고 쓰는 함수가 없으므로 MSR에 관련된 어셈블리어 함수부터 만들겠습니다.


*. 2546 Page, "[표 50-2] e_entry 필드의 세부 구성과 의미"를 "[표 50-2] e_ident[16] 필드의 세부 구성과 의미"로 변경


*. 2546 Page, 아래에서 7번째 줄

가장 먼저 할 일은 e_ident 필드의 상위 4바이트가 매직 넘버이므로, 파일의 첫 4바이트가 매직 넘버와 일치하는지를 검사하여 올바른 ELF64 파일인지 확인하는 것입니다.


*. 2548 Page, 아래에서 5번째 줄

현재 섹션의 타입에 따라 필드의 의미가 달라지며 자세한 내용은 [표50-6]을 참조


*. 2616 Page, 위에서 첫번째 줄

[그림 51-2]는 이러한 처리 과정을 나타낸 그림입니다.


*. 2625 Page 위에서 14번째 줄,  2641 Page 아래에서 8번째줄, 2785 Page 밑에서 7번째줄, 

// 현재 라인에서 남은 문자 수와 한 라인에 출력할 수 있는 문자 수 를 비교하여 작은 것을 선택


*. 2692 Page, 위에서 12번째 줄

g_stGameInfo.iBlockX = -1;

g_stGameInfo.iBlockY = -1;


*. 2693 Page, 위에서 10번째 줄

게임판의 블록이 존재하는지 여부는 게임 자료구조의 vvbBoard 필드에 저장되어 있습니다.


*. 2694 Page, 위에서 5번째 줄

게임 자료구조에는 현재 게임판의 정보를 저장하는 vvbBoard 필드가 있으므로 움직이는 블록의 현재 좌표를 그대로 게임판에 저장하면 됩니다.


*. 2720 Page, 아래에서 13번째 줄

g_stGameInfo.iBlockX = -1;

g_stGameInfo.iBlockY = -1;


*. 2766 Page, 위에서 4번째 줄

텍스트 뷰어에 한글 출력 기능을 추가하려면 한글인지를 판단해 2바이트씩 출력하는 코드만 추가하면 되기 때문입니다.


*. 2846 Page, 위에서 1번째 줄

만든 첫 번째 한글 입력 모듈은 오토마타를 사용했습니다.


*. TODO...


"64비트 멀티코어 OS 원리와 구조" 책의 첫 서평이 올라왔습니다. ㅠㅠ 
(다행히도 서평이 좋네요. ㅠㅠ 감사드립니다. ㅠㅠ)

<64비트 멀티코어 OS 원리와 구조 - 출처 yes24.com>

서평을 써주신  somesing님, charsyam님, niceness님, ageman1님 감사드립니다.  ㅠㅠ

앞으로 더욱 열심히하는 kkamagui가 되겠습니다. (__)

 
ps)  다들 즐거운 추석 연휴 보내세요 ;) 

<64비트 멀티코어 OS 원리와 구조>


MINT64 OS의 챕터별 예제 소스는 한빛 미디어 웹사이트(www.hanb.co.kr/exam/1836)로 이동하면 받을 수 있습니다.
해당 링크로 이동하면 source_code.zip 파일cygwin_devenv.zip 파일을 볼 수 있습니다.

source_code.zip 파일: 
   각 장별 소스 코드가 담겨 있으며, MINT64 OS를 실행할 수 있는 환경과 각종 데이터 시트를 모아 놓았습니다.
   (책에서 언급한 부록 CD의 내용은 대부분 여기에 들어있습니다. ^^)

cygwin_devenv.zip 파일:
   제가 개발하던 당시 Cygwin 디렉터리를 압축한 것입니다. 
   일반적인 경우라면 최신 버전의 Cygwin을 내려받아서 환경을 구성합니다. 
   하지만 크로스 컴파일러를 만드는데 계속 실패하거나 알 수 없는 오류가 발생한다면 
   cygwin_devenv.zip 파일의 압축을 풀어 C:\cygwin 디렉터리에 덮어써서 문제를 해결할 수 있습니다. ^^


그럼 즐거운 OS 프로그래밍하시고, 출간 기념 이벤트(http://kkamagui.tistory.com/748)도 많이 참여해주세요 ^^
오늘 드디어 그렇게 기다리던 "64비트 멀티코어 OS 원리와 구조"가 제 손에 들어왔습니다. ㅠㅠ 지금까지 A3 용지에 출력된 것만 보다가, 이렇게 책으로 제본된 것을 보니 왠지 울컥(?) 하더군요. ㅠㅠ 그래서 뭔가 저질러야겠다는 생각이 들어서 출간 기념 이벤트를 하기로 했습니다. ^^)/~ 

<64비트 멀티코어 OS 원리와 구조의 실물 사진>


이벤트 응모 방법은 아주 간단합니다. 오늘부터 배송이 시작되었다고 하니 빠르면 내일부터 책을 받으실 겁니다. 그러면...

책을 받았다는 인증 사진을 찍어 저에게 메일(mint64os@gmail.com)로 보내시거나, 블로그에 올리시고 제가 볼 수 있게 이 글(http://jsandroidapp.cafe24.com/xe/216)의 댓글로 링크를 남겨주시면 됩니다. 

그러면 제가 정확히 7월 31일에 랜덤(?)으로 추첨하여 공정하게 1분을 뽑아 소정의 선물을 드릴까합니다. ^^)/~
(7월 31일 자정에 추첨하겠습니다. ^^;;;)

선물은 책을 보시는데 꼭 필요한 것으로 준비할 예정이니 많은 응모 부탁드립니다. ^^

ps) 실제로 보니 책이 정말 잘 나왔네요. 분량이 많아서 내심 걱정했는데, 내용도 알맞게 잘 편집된 것 같습니다. 아주 마음에 쏙~!! 드는군요. :) 

 

<책 표지>


제가 2008년부터 만들기 시작한 MINT64 OS에 대한 책, "64비트 멀티코어 OS 원리와 구조"가 나왔습니다. ㅠㅠ 제 블로그를 방문하시는 분은 이미 알고 계시겠지만, 2008년 말에 취미로 64비트 모드에 발을 담갔다가 그대로 64비트에 멀티코어를 지원하는 OS까지 내리 달렸습니다. 그리고 내친김에 GUI에 응용프로그램까지 제대로 한번 해보자는 생각에 2년 넘게 작업을 했더랬지요. 제가 그간 진행했던 과정은 http://kkamagui.tistory.com/category/OS%20Kernel/MINT64%20OS 에서 보실 수 있습니다. ^^;;;

2008년부터 작업 과정을 올리면서 소스 공개를 바라시는 분들이 많았는데, 조금만 더 정리하고 올린다고 했던게 벌써 3년이나 지났네요. 쿨럭..;; 죄송합니다. ㅠㅠ 그래도 소스코드와 덤으로 제가 했던 작업 내역까지 상세하게 풀어쓴 책까지 공개했으니 너그러이 용서해주세요. ^^;;; 

<MINT64 OS의 실행 화면>


책은 2권으로 이루어져 있고 분량은 대충 2800 페이지 정도 됩니다. 페이지만 봐도 얼마나 내용이 자세한지는 대략 추측할 수 있을 꺼라 생각합니다. OS 만들기가 그렇지만 어셈블리어나 C 코드 한 줄만 틀려도 재부팅되거나 멈추기 때문에, 작업한 내용을 최대한 빼먹지 않도록 노력했습니다. 이 책을 보면 제가 부트로더부터 GUI를 거쳐 응용프로그램을 만들기까지 모두 들어있기 때문에, 장담컨데 이 책만 있으면 누구나 "취미"로 64비트와 멀티코어를 지원하는 OS를 만들 수 있습니다~!! 


글을 올리고 하루만에 판매가 시작되었네요. ^^;;;; 주요 서점에서 구하실 수 있구요, 링크는 아래와 같습니다.


1권 도서 링크 : http://www.yes24.com/Product/goods/65061299(ebook)http://www.yes24.com//24/goods/5270659(종이책) 

2권 도서 링크 : http://www.yes24.com/Product/goods/65061297(ebook)http://www.yes24.com//24/goods/5270667(종이책)

1/2권 세트 도서 링크 : http://www.yes24.com//24/goods/5271779(종이책)


종이책은 현재 절판 상태이니 ebook을 이용해주시면 감사하겠습니다. ^^;;;

그럼 다들 즐거운 하루 되세요 ^^


ps 1) 책이 나오기까지 도움을 주시고 응원해주신 많은 분들께 진심으로 감사드립니다. (__)

      이 책이 나올 수 있었던 것은 다 여러분들 덕입니다.
ps 2) 아래는 MINT64 OS의 구동 화면입니다. 화면 캡쳐를 하다보니 끊기는 부분이 보이는데, 실제로 실행하면 좀더 부드럽습니다. ^^;;;




+ Recent posts