Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

kernel process의 stChildThreadList를 초기화 하지 않음으로써 실제 컴퓨터에서 구동이 안되는 문제와 그에 대한 해결방안 #8

Open
ybjeon01 opened this issue Jul 4, 2021 · 2 comments

Comments

@ybjeon01
Copy link

ybjeon01 commented Jul 4, 2021

안녕하세요. Ch21를 코드 작성을 마치고 실제 컴퓨터에서 구동하는 테스트중에 General Protection Exception이 발생하게 됐습니다. 그리고 이 문제가 이 GitHub 코드에도 똑같이 발생할 문제인 것 같아 글을 올립니다.

Ch21의 kCreateTask 함수를 보면 모든 process의 멤버중 하나인 stChildThreadList를 초기화합니다. 하지만 딱 하나 초기화가 되지 않은채 실행되는 task가 하나 있는데요. 바로 kernel process입니다. 단순히 이 커널 프로세스의 thread를 생성하지 않으면 아무 문제없이 운영체제가 잘 작동합니다. 하지만 문제는 kIdleTask 함수가 이 커널 프로세스의 thread로 작동하면서 발생합니다.

이 커널 process는 kInitializeSchedule 함수안에서 생성되는데 stChildThreadList가 초기화 되지가 않습니다. 초기화가 안된 stChildThreadList 안의 멤버들은 의도되지 않는 숫자가 들어가 있는 상태에서 kCreateTask 함수가 kIdleTask의 qwID를 부모 process (kernel process)의 list에 연결할 떄 존재하지 않는 메모리 참조가 일어나면서 general protection exception이 발생되는걸 확인했습니다.

좀 더 쉽게 눈으로 확인하기 위해서 비디오를 남깁니다. 그리고 원래 코드와 바뀐 코드도 함께 올렸습니다. 수고하세요.

Original Code (02.Kernel64/Source/Task.c)

void kInitializeScheduler( void )
{
    // 함수의 윗부분을 생략했습니다.
    
    pstTask->qwParentProcessID = pstTask->stLink.qwID;
    pstTask->pvMemoryAddress = ( void* ) 0x100000;
    pstTask->qwMemorySize = 0x500000;
    pstTask->pvStackAddress = ( void* ) 0x600000;
    pstTask->qwStackSize = 0x100000;
    
    // 프로세서 사용률을 계산하는데 사용하는 자료구조 초기화
    gs_vstScheduler[ bCurrentAPICID ].qwSpendProcessorTimeInIdleTask = 0;
    gs_vstScheduler[ bCurrentAPICID ].qwProcessorLoad = 0;
    
    // FPU를 사용한 태스크 ID를 유효하지 않은 값으로 초기화
    gs_vstScheduler[ bCurrentAPICID ].qwLastFPUUsedTaskID = TASK_INVALIDID;
}

Modified Code

void kInitializeScheduler(void) {
    // 이 함수의 윗부분을 생략했습니다.

    pstTask->qwParentProcessID = pstTask->stLink.qwID;
    pstTask->pvMemoryAddress = (void *) 0x100000;
    pstTask->qwMemorySize = 0x500000;
    
    pstTask->pvStackAddress = (void *) 0x600000;
    pstTask->qwStackSize = 0x100000;

    // 바뀐 부분
    kInitializeList(&(pstTask->stChildThreadList));
    

    // initialize variables that help to calculate processor load
    gs_stScheduler.qwSpendProcessorTimeinIdleTask = 0;
    gs_stScheduler.qwProcessorLoad = 0;
}

(근데 시간 나시면 mint64OS 사이트에 올린 제 질문들 좀 확인해줄 수 있나요? linuxer라는 닉네임으로 활동하고 있습니다. FreeBoard와 QnA 게시판에 한 4개정도 올렸습니다. 바쁘지 않을 때 천천히 확인해주세요.)

@kkamagui
Copy link
Owner

kkamagui commented Jul 5, 2021

안녕하세요, @ybjeon01 님!

앗, 감사합니다. 초기화되지 않은 필드가 있었군요! 제가 보고 시간날 때 반영하겠습니다.

그런데 혹시 시험은 어디서 하셨는지 알 수 있을까요? 운영체제 환경이랑 시험용 가상머신 환경 등을 알려주실 수 있을까요?

감사합니다.

ps) 사이트에 남기신 질문도 제가 확인하겠습니다. ^^)-b

@ybjeon01
Copy link
Author

ybjeon01 commented Jul 5, 2021

그럼요. 알려줄 수 있죠.

개발 환경

  1. CPU: Intel Core i5-7200U Dual-Core (x86_64)

  2. OS: Windows 10 (x64)

  3. Docker: v20.10.7 with WSL2

  4. Container: Ubuntu 20.04.2 LTS (Focal Fossa)

  5. Tools installed in container:

    • NASM version 2.14.02
    • GCC (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0 # 추후 cross compiler로 바꿀 예정입니다.
    • GNU ld (GNU Binutils for Ubuntu) 2.34
    • GNU Make 4.2.1
  6. IDE: Visual Studio Code # Linux container에 Visual Studio Code 서버 설치하고 Windows에서 Client 실행하는 게 가능합니다)

  7. Image Writer: Rufus version 3.0.1304

테스트 환경

  1. 가상 환경: QEMU emulator version 6.0.0 (v6.0.0-11869-g800a25ea45-dirty) for Windows

  2. 실제 PC: Samsung Series 5 NP530U3B

    • 1.6GHz Intel Core i5-2467M Dual-Core (x86_64)

부가 설명

  1. Windows와 Docker Container사이에 공유되는 volume을 하나 추가해서 사용하고 있습니다. 모든 활동을 이 volume안에서 하고 있어서 컴파일이 끝나면 바로 Windows 환경에서 사용할 수 있게끔 했습니다.

  2. Windows환경에서 작동하는 QEMU emulator에 kernel 파일을 실행했습니다.

  3. Rufus image writer는 Windows 환경에서만 작동합니다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants