회사에서 시간이 좀 남아서 정리를 하던 중에, 재미있는 글을 발견했습니다. 글 주제는 Core의 수가 점점 증가하는 것이 대세이고, 이것을 효율적으로 지원하는 것이 처리 속도를 향상시키는데 도움이 될 것이라는 내용이었습니다. 그 문서에 Intel 사이트의 웹페이지 링크가 첨부되어 있었는데... CPUID를 사용해서 물리적인 Core Processor와 Hyper Threading Logical Processor의 수를 검사하는 방법이 나와 있었습니다.

나름대로 깔끔한 문서라서 회사에서 킵(?) 한 다음 집에 와서 키워드로 검색하니, 이번에는 동영상 강의가 나오더군요. @0@)-b PDF로 작성된 문서보다 훨씬 깔끔하게 정리되어 있어서 공유 차원에서 올립니다. 동영상 강의는 http://software.intel.com/en-us/articles/hyper-threading-technology-and-multi-core-processor-detection 에서 볼 수 있습니다.

제가 만드는 MINT64 OS에서는 Performance를 크게 고려하지 않기 때문에, Core Processor인지 Hyper-Threading Logical Processor 인지 굳이 구분하지 않습니다. 만약 같은 Package에 있는 같은 Core인가, 아니면 같은 Core에 있는 Hyper-Threading Logical Processor인가 판단하여 적절하게 스케줄링하면 보다 높은 Performance를 낼 수 있을 것 같지만... 자세한 건 실제로 벤치마킹한 문서를 봐야 알 것 같습니다. 나중에 시간 나면 Core나 Hyper-Threading에 따라서 어떻게 스케줄링해야 하는지도  한번 봐야겠습니다. ㅎㅎ

차 시간이 다가와서 이만 가야겠군요. ;) 다들 메리 크리스마스~!!!

image

어제 후배에게 테스트를 부탁한 뒤로 생각한 것인데, 각 PC 별로 64bit 및 멀티 코어 검사에 문제가 없는지 확인할 필요가 있을 것 같습니다. 지금 상황으로 보니 프로세서가 64bit 모드를 지원하더라도 BIOS나 기타 문제 때문에 64bit로 전환되지 않는 문제가 있는 것 같더라구요. ㅎㅎ

좀더 자세한 내용은 실제로 테스트를 해봐야 알겠지만... AMD 프로세서 쪽도 체크해 볼 필요가 있을 것 같습니다. 지금까지는 Intel이나 AMD나 64bit 쪽 전환하는 과정이 같다고 가정하고 작업을 했었는데... 순간 아닐 수도 있다는 생각이 들었습니다. 마침 이번 주가 즐거운 크리스마스고 고향집(홈 스윗 홈~!!!)으로 내려갈 예정이니 고향집에 있는 PC(AMD PC)를 마구 굴려서 정보를 뽑아 낼 예정입니다. 그리고 테스트 결과를 여기 블로그나 스프링노트쪽에 올려야겠습니다.

이거 원~!!! 할 일이 태산이군요. ;) 그나마 다행인 것은 틈틈이 책을 좀 봐서 리뷰는 대충 끝냈다는 거~!!! 이제 문서만 만들면 되는데... 왜 이렇게 문서를 만들기가 귀찮은지... 그냥 스프링노트에 끄적거린걸 바로 날려 버리고 싶은 충동이 마구 마구 밀려옵니다. ㅠㅠ)-b 그래도 처음하는 리뷰이니만큼 신경을 좀 쓰긴 써야 할 것 같군요. ㅎㅎ 아흙~!! ㅠㅠ

에궁... 이제 그만 슬슬 자야겠습니다. 사실 잔다기 보다는 몬스터 헌터 2G에 재미를 붙여서 그거 좀 하다가 잘려고... (‘’ )a... 이래도 되는 건지 잘 모르겠군요. ㅠㅠ)-b

그럼 다들 좋은 밤 되시고, 크리스마스 준비 잘하시길~ ;)

ps) 윗부분에 스크린샷은 A20 게이트를 활성화하고 찍은 겁니다. ㅎㅎ 뭐 키보드 컨트롤러를 사용해서 On 하는 건 이제 구식이라 BIOS와 시스템 컨트롤 포트를 사용해서 깔끔하게 처리했습니다. ;) 세상 참 좋아졌군요. ㅎㅎ

지금 A20 Gate에 대한 내용을 정리하고 있습니다. 뭐 예제로 보는 것이 가장 확실해서 간단한 예제를 하나 만들어 제 PC에 동작시켜 봤는데... 일반적인 상황이라면 분명히 죽어야 하는 예제인데 이상하게 버젓이 살아서 동작하는 겁니다. @0@... 혹시나 해서 이것 저것 테스트 해봤습니다만, A20 Gate 쪽이 완전히 동작하지 않는 것 같았습니다. 이제 XT 시절에 쓰던 프로그램을 다시 돌릴 일이 없으니, 무의미하긴 하지만.... 없으니 뭔가 좀 허전하더군요. 에러를 발생시키기 위해서 A20 Gate를 비활성화 했음에도 불구하고 잘 동작하는 것 보면 작동 안 한다고 보는 것이 맞겠지요. ㅎㅎ

혹시나 해서 후배 PC에 돌려봤는데, 일단 후배 PC는 자동으로 A20 Gate가 켜지는 건 아닌 것 같았습니다. A20 Gate를 끄고 OS를 부팅했을 때는 계속 리부팅 되더라구요. ^^;;; 그런데 이상한 점은 64bit 모드로 전환되지 않는 다는 것이었습니다. 정상적인 상황이라면 64bit로 전환되어 커널이 실행되어야 함에도 불구하고 64bit로 전환하는 곳에서 멈춰 있었습니다. ㅡ_ㅡa...

원인은 좀 더 살펴봐야 알겠지만... 살짝 골치가 아프네요. ㅎㅎ 이거 원... 프로세서가 64bit를 지원하는 것 만으로는 안되는 것이 있나 봅니다. ㅠㅠ 어흑... 머리야...


ps) A20 게이트와 주소 공간에 대해서는 따로 정리를 한번 했습니다. ;)

http://kkamagui.tistory.com/619

아우~ 이번 내용에 대한 정리는 지난 주부터 시작했는데, 이것 저것 일이 많아서 진도가 굉장히 안 나가는군요. ㅠㅠ 특히 온 주말을 디버깅에 투자했더니 더 그런 것 같습니다. ㅎㅎ 사실 한번 만들었던 걸 다시 만들려니 더 진도가 안 나가는 것 같기도 하네요. ㅎㅎ

드디어 기나긴 어셈블리어의 늪을 빠져 나와 C 코드로 접어들었습니다. 이제 대부분의 작업을 C 코드로 할 수 있겠군요. ㅎㅎ 물론 중간 중간에 꼭~!!! 어셈블리어로 처리해야 하는 부분이 있어서 완전히 빠져 나왔다고 보기는 어렵지만, 어찌되었든 C 코드를 쓸 수 있다는 데 의의가 있으니... ^^;;;

아흙...회식에서 술을 좀 퍼먹고 왔더니, 체력이 거의 바닥입니다. ㅎㅎ 자면서 코딩해서 내일 다시 뒤집어 엎는 게 아닌가 슬슬 걱정이 되는군요. 일단 뭐 대충 이만하면 됐으니 그만 자야겠습니다.

다들 좋은 밤 되세요 ;)

거의 이틀 간의 삽질 끝에 부팅에 성공했습니다. ;) 물론 한번에 성공한 건 아니고, 여러 문제가 있었습니다. ^^;;;; 것 참... 버그가 한 두 개가 아니더군요.


첫 번째 버그는 IDE 하드를 체크하는 루틴에 있었습니다. 가상 PC에서는 IDE를 사용한다는 가정하에 코드를 작성했는데, 실제 PC는 SATA였기 때문에 동작하지 않더군요. ^^;;; 원래는 타이머를 체크하면서 검사하게 되어 있었는데 인터럽트 불가 루틴이 앞에 있어서 결국 타이머가 이벤트가 발생하지 않았고 무한 루프를 돌았다는... ㅠㅠ


두 번째 버그는 대충 만든 동적 메모리 할당 루틴 때문이었습니다. 이상하게 어디서 int 타입으로 계산했는지 2GB 이상의 어드레스의 메모리를 할당 받으면 sign extension이 일어나서 Unsigned Long 타입으로 받았을 때 상위 32bit가 모두 0x0F로 설정됐습니다. ㅠㅠ  가상 PC에는 메모리를 최대 64MB로 설정해 놨기 때문에, 발견되지 않았더군요. 크윽...


세 번째는 MTRR 레지스터를 잘 못 설정해서 생긴 문제였습니다. ㅠㅠ 어설프게 배웠더니(?) 홀수 MB 메모리는 캐시를 사용하도록 설정하고 짝수 MB는 캐시를 사용 안 하도록 설정했더군요. 그 덕분에 굉장히 느린 GUI 화면을 볼 수 있었습니다. ㅡ_ㅡa... 어찌나 느리던지... RDTSC를 통해 CPU 속도도 재보고, 프로파일러를 만들어서 화면 업데이트 속도도 재 봤는데... 헉... 초당 3 프레임 정도 나왔습니다. 하도 이상해서 램, 비디오 램 두 영역을 잡아서 1024 * 768 * 2 Byte를 동일한 함수에서 채워 봤습니다. 얼래... 램이랑 비디오 램이랑 둘 다 비슷하더군요. ㅡ_ㅡa... 램 영역은 캐시를 활성화 하도록 했기 때문에 원래대로라면 램이 더 빨라야 하는데 말이죠. ^^;;;; 결국 잘못 셋팅해서... ㅠㅠ


이런 자잘한(?) 문제를 다 해결하고 나서야, 광속(?)으로 동작하는 MINT64 OS를 볼 수 있었습니다. 코드 두줄 바꿨을 뿐인데 정말 빠르더군요. ㅠㅠ)-b 크윽... 초당 3프레임 나올 때는 진짜 띵~ 하던데...ㅠㅠ 기념으로 사진을 찍어서 올립니다. ㅎㅎ 동영상을 찍고 싶었지만 카메라가 꾸져서... 다음에 디카를 사면 한번 찍어 올리겠습니다. ㅎㅎ


이제야 다시 정리(?)하는데 집중할 수 있겠군요. 덕분에 주말의 2/3을 날렸네요. ㅎㅎ 그래도 기분은 좋습니다. ;) 앗싸 MINT64 OS 만세~!!!


ps) 이번에 좁은 책상을 버리고 퍼즐 형태의 사무용 책상으로 바꿨더니 작업 능률이 200%는 올라간 것 같습니다. 역시 작업 환경은 무조건 좋고 봐야 합니다. ;) 그지? 후배야? ㅋㅋ

지금까지 만들기만 실컷 만들고 플로피 드라이브와 디스크가 없어서 테스트를 못하고 있었습니다. 그러다 오늘 문득 USB에 심으면 바로 테스트 할 수 있겠다는 생각이 들더군요. 그래서 부트 로더를 좀 수정한 다음 USB에 옮겨 담으니 떡!! 하고 부팅이 됐습니다. @0@)-b

물론 한번에 된 건 아니고, 이것 저것 설정 문제 때문에 삽질을 좀 많이 했습니다. 대략 8시부터 시작했는데, 벌써 2시군요. ㅡ_ㅡa... 거의 6시간 동안 작업했다는.... 그런데 좀 이상한 건 듀얼 코어 활성화에 64bit 전환, 그리고 램도 거의 4기가까지 잘 잡히는데... 윈도우가 굉장히 느리더군요. ㅡ_ㅡa... 뭔가 이상했습니다. 가상 머신에서 테스트하는 것 보다 더 느리게 동작했습니다. ㅠㅠ

hlt() 루틴도 빼 보고 타이머 인터럽트의 회수도 줄여 봤지만... 테스트를 하면 할수록 클럭의 속도가 낮게 잡힌 것이 아닐까 하는 생각이 들더군요. 물론 BIOS에서 스피드 스텝 옵션은 끈 상태였습니다. 아우... 당췌 무슨 일인지... 일단 오늘은 밤이 늦었으니 이만하고... 내일은 튜닝을 좀 한 다음 인증 샷을 올리겠습니다. ;)

그럼 다들 좋은 밤 되세요 ^^)-b

ps) 정리해야하는데, 다시 일을 벌이는 듯한 느낌이군요. 만약 스피드 스텝쪽 문제라면 왠지 챕터 하나가 더 늘어날 듯 하다는... ㅠㅠ 아흙... 미쵸...

OS를 만들면서 지금까지는 makefile을 거의 배치 파일 수준으로 사용하고 있었습니다. 이게 무슨 말이냐 하면... 디렉토리에서 소스 파일 이름만 달랑 추출하고, .C 파일과 같은 소스 파일이 수정되었을 때만 커널을 다시 빌드한다는 이야기입니다. 귀차니즘때문에 이렇게 쓰시는 분들이 많을 것 같다는... ^^;;;; 이렇게 되면 헤더 파일이 수정되었을 때, 해당 헤더 파일을 당겨쓰는 .C 파일들이 자동으로 빌드되지 않기 때문에 문제가 생깁니다.

뭐, 사실 혼자 테스트 할때는 매번 Clean해서 전부 삭제하고 다시 빌드하면 되니 신경을 안썼는데... 거사(?)를 치루려다 보니 이런것 하나하나가 신경 쓰이더군요. 결국 makefile을 뒤엎어서 의존성 관련 부분을 추가했습니다. 거의 3시간 정도 이것만 한 것 같네요. ㅠㅠ

C 파일로 부터 의존성 정보를 뽑는건 아주 간단합니다. "gcc -c -M Main.c Main2.c > a.txt" 와 같이 옵션을 주면 아래와 같이 이쁘게 출력해 줍니다. 이렇게 생성한 a.txt 파일을 makefile에 포함시켜주면 나머지는 규칙에 따라서 알아서 빌드해 줍니다. :)
Main.o: ../Source/Main.c ../Source/Main.h
Main2.o: ../Source/Main2.c

makefile에 포함시키려면 다음과 같이 써주면 됩니다. $(wildcard a.txt)는 디렉토리에서 a.txt 패턴이 들어간 파일명들을 스페이스바로 구분한 리스트를 나타내며, ifeq는 두 항목을 비교하는 것입니다. 즉 아래 코드는 같은 디렉토리에 a.txt가 있으면 해당 파일을 makefile에 포함시키라는 의미입니다.
ifeq (a.txt, $(wildcard a.txt))
include a.txt
endif

위의 내용을 추가해서 만든 makefile을 실행한 것입니다. 의존 관계에 대한 정보가 아주 자알~ 생성되고 있음을 볼 수 있습니다. ;)
C:\MINT64\01.Kernel32>make dep
make -C Temp -f ../makefile InternalDependancy
make[1]: Entering directory `/c/MINT64/01.Kernel32/Temp'
gcc.exe -c -M ../Source/Main.c ../Source/Main2.c > .dependancy
make[1]: Leaving directory `/c/MINT64/01.Kernel32/Temp'

아아~ 이거 원... 마음이 급해서 날림으로 만들었더니, 이런데서 시간을 많이 잡아먹는군요. ㅎㅎ 하루를 그냥 날린 것 같습니다. ㅠㅠ 나머지 작업은 할 수 없이 내일 해야겠네요. ;)

그럼 다들 좋은 밤 되세요 ;)

에궁 에궁~ 요즘 글 정리하랴 OS 코드 정리하랴 정신이 없습니다. 정리하던 도중에 OS의 구조가 바뀌는 바람에 또 한번 식겁(?)을 하고 겨우 다시 원점으로 되돌려 놨습니다. ^^;;;; 지난번까지는 모두 어셈블리어로 작업을 했었는데, 이제 C 코드를 같이 빌드할 수 있게 되었습니다. 덕분에 작업이 더 수월해 지겠군요. >ㅁ<)-b

image

아우~ 했던 작업을 또 할려고 그러니 귀찮은 것도 있고, 정리도 하려니 시간이 아주 좔좔 들어가는군요. ㅠㅠ 잠을 좀 자긴 자야 할텐데... 큰일입니다. ^^;;;; 일단 오늘도 늦었으니 이만 자고 나머지는 내일 정리해야겠군요.

다들 좋은 밤 되세요 ;)

에궁... 좀 전까지 해서 보호 모드로 전환하는 내용까지 대충 마무리했습니다. 이제 좀 더 손본 다음 메모리를 잠시 정리하고 64bit로 전환하면 되겠군요. 화면 캡처하랴 그림 그리랴 표 만들랴 완전 정신 없습니다. ㅠㅠ

아우 어찌나 길고 험난한지... 아주 죽을 맛입니다. ㅠㅠ 그래도 찔끔 찔끔 진도가 나가고 있으니 그나마 다행이네요. ㅎㅎ 일단 오늘은 몹시 피곤하니 일찍 자야겠습니다. 다들 좋은 밤 되세요 ^^

에궁~ 드디어 지루했던 부트 로더에 대한 내용을 완료했습니다. 이제 32bit 보호 모드로 전환하는 과정부터 해서 64bit 모드로 전환하는 과정까지의 내용을 다룰 차례인데, 이것 또한 한 두 챕터로 끝날 것 같지 않네요. ^^;;;; 64bit 모드로 전환하는 내용까지만 어찌 어찌 진행되면 나머지는 내용이 그리 많지 않을 것 같은데 말이지요. 끄응...

12월에 거사를 치를 생각인데, 개인적인 바램은 거사 전에 64bit 모드 전환까지 내용을 다룰 수 있었으면 하는 것입니다. 사실 앞부분이 CPU에 굉장히 의존적인 부분이라 설명할 것도 많고, 구현 할 것도 많거든요. ㅠㅠ 아흑... 이제 곧 12월인데 가능할지 모르겠습니다. 목차도 한번 정리해야 하는데... 정신 없이 뽑았더니 목차를 너무 세분화해서 한 챕터 분량이 아닌 것도 더러 있었습니다. 아흑... 진짜 미쵸... ㅠㅠ

일단 오늘은 몸이 않 좋아서 일찍 자야겠습니다. 그리고 나서 내일은 무한 버닝~!!!! @0@)-b 주말에 콱 그냥 다 써버리는 센스를~!!! ㅎㅎ

그럼 다들 좋은 밤 되세요 ^^)/~

요즘 일 때문에 MINT64 OS라는 이름으로 새로 코드를 정리하고 있습니다. ㅎㅎ 이번에는 부트 로더에 OS 이미지를 로딩하는 기능을 추가하는 내용 때문에 만들었는데, 로딩하는 기능을 만들고 나니 커널이 없어서 테스트할 수가 없더군요. ㅠㅠ 그래서 가상 OS 이미지를 만든 후, 이를 부트 로더가 로딩하여 실행하도록 했습니다.

1024 섹터의 가상 OS 이미지를 만들어야 했는데, 처음에는 코드 블럭을 매크로를 만들어서 반복하려고 했습니다. 그런데 동일한 매크로를 1024번 반복해서 입력하려니 이것도 일이더군요. ㅡ_ㅡa.. 그래서 NASM 문서를 살펴봤더니 묘수가 떠올랐습니다. 바로 전처리기 문법을 사용하는 것입니다. 전처리기를 사용하니 엄청 간단하게 되더군요. @0@)-b 나중에 NASM 전처리기 문법에 대해서도 한번 정리할 필요가 있을 것 같습니다.  ㅎㅎ

아래는 가상 OS 이미지를 부트 로더가 로딩한 후 실행한 화면입니다. 1024개의 0~9가 정상적으로 실행되었다는 것을 표시하고 있습니다.

이제 조금만 더 정리하면 32bit 커널까지 가겠군요. 어찌 이래 갈 길이 먼지... ㅎㅎ 진짜 시간이 장난 아니게 걸리네요. ㅎㅎ 뭐 설마 밑 빠진 독에 물 붓기겠습니까? ^^;;; 언젠가는 차겠지요. ㅎㅎ

에궁~ 이만 자야겠습니다. 다들 좋은 밤 되세요. ㅎㅎ

오늘도 어김없이 글을 정리하면서 BIOS 서비스 루틴에 대해서 쓰고 있었습니다. 보통 위키피디아를 많이 찾는데, 오늘은 왠지 구글신에게 물어 보고 싶더군요. 역시나 멋진 링크를 보내 주셨습니다. 만세~!!!!


http://bioscentral.com/misc/biosservices.htm

http://www.htl-steyr.ac.at/~morg/pcinfo/hardware/interrupts/inte1at0.htm


위의 링크로 가면 BIOS 서비스 루틴 및 기타 BIOS 관련 자료들을 쉽게 찾을 수 있습니다. 아주 잘 정리되어 있더군요. ㅎㅎ 좋구로~!! 이렇게 일거리가 또 하나 줄어든다는~!!!

아래는 이번에 정리하면서 새로 만든 부트 로더의 화면입니다. 아무래도 따라하기 식의 내용이다 보니, OS를 완전히 처음부터 다시 만들고 있습니다. ㅎㅎ 이제 조금만 더 있으면 OS 이미지를 로딩하고 실행하는 화면이 나오겠군요. ;)

OS 이름 때문에 상당히 고민했는데, 그냥 MINT(민트)64 OS로 정했습니다. Multi-core INTelligent 64bit OS의 약자로 멀티 코어를 지원하는 똑똑한 64bit OS라는 의미입니다. ㅎㅎ 약간 촌스럽긴 하지만, 여자 친구의 강력한 지지가 있어서.. ^^;;; (후배야 쏘리 ㅠㅠ 횽 맘 알지? ㅋㅋ)

어휴... 코딩하려 글 적으랴... 내용 검증하랴... 시간이 무지 부족하군요. ㅡ_ㅡa... 이래서는 영 답이 안 나오는 데... 어떻게 해결 방법을 찾아야겠습니다. 반드시 말이죠. ㅠㅠ

엇, 고민하는 사이 벌써 잘 때가 됐군요. 다들 좋은 밤 되시고, 감기 조심하세요 ;)

여자 친구가 와서 주말 내내 바이오 하자드를 했습니다. ㅡ_ㅡa.. 역시 여자 친구가 헤어나질 못하더군요. ㅎㅎ 어찌나 재미있어 하던지… 덕분에 벌써 Easy 모드 끝판을 깼습니다. ㅡ_ㅡV 여자 친구가 기뻐하는 모습을 보니 사기를 잘했다는 생각이 드네요. ^^;;; 평소에 뭐하나 제대로 해준 게 없었는데, 이걸로 어느 정도 만회한 것 같습니다. 앗싸~!!!

덕분에 이번 주말은 거의 진도를 못 뺐네요. ㅎㅎ 그래도 세상에서 가장 간단한 부트 로더(?)를 만드는 내용까지는 진도를 나갔으니 다행입니다. 어찌나 간단한지 정신이 휑~ 해질 정도입니다. 이래서야 욕이나 얻어 먹지 않을까 걱정이 되는군요. ^^;;;;; 그래도 처음에는 뭐든지 다 힘들고 어려우니, 이 정도 내용은 되야 어떤 사람(?)이라 충분히 따라올 수 있을 꺼라고 위로하면서 쓰고 있습니다. 과연... 그럴지는 저도 잘… ㅠㅠ

개구리가 올챙이적 모른다고... 처음에 OS를 만들 때는 힘들고 어려운 게 사무쳐서 내가 나중에 잘 알게 되면 이런 이런 내용을 주로 다뤄야겠다고 생각 많이 했었는데... 지금은 그런 내용들이 하나도 생각 안 나는군요. 오히려 지금은 당연히 알고 있어야 하는 내용이라고 생각도 하는 부분도 있어서 상당히 조심스럽습니다. 아무래도 이런 가정들이 하나 둘 늘어 가다 보면, 중요한 내용을 빠뜨릴 것 같다는 느낌 때문일 겁니다. ^^;;;

어휴… 역시나 쉽지 않군요. 그래도 일단 달려 보겠습니다. 듬직한 후배들만 믿고 말이죠. ;)

ps) 이 글을 보고 있는 후배야... 바로 너란다 ㅋㅋ 앞으로 잘 부탁하께 ㅋㅋ

아아~ 이거 글 쓰는 일이 쉽지 않군요. 챕터 하나 쓰는데 거의 3주 동안 하고 있습니다. 물론 그 중에 2주는 퇴근을 완전 늦게 해서 작업할 시간이 부족한 것도 있지만… 내용 자체가 워낙 많다 보니 장난이 아닙니다. @0@

지금 A4로 거의 30쪽째 쓰고 있는데, 퇴고 할 때마다 자꾸 내용이 추가됩니다. ㅠㅠ 챕터의 주제는 64bit 프로세서에 대한 내부 설명입니다만, 왜 이걸 넣었는지 후회가 되는군요. 실제로 코딩을 진행하면서 각 챕터 관련된 부분은 다시 설명할 예정이라 간단하게 정리하려고 시작했는데, x86-64 프로세서가 워낙 복잡하다 보니 쉽게 끝나지가 않습니다.

리얼 모드 + 보호 모드 + IA-32e 모드의 3가지에 대해서 각각 세그먼테이션, 페이징에 대해 설명하니 총 5개 정도가 되고, 그 앞에 각종 레지스터와 모드에 대한 설명이 또 들어가니 양이 정말 장난 아닙니다. ㅠㅠ 쓰는 것도 일이지만 퇴고하는 것도 일이군요. 어제 오늘 거의 4시간씩 투자하면서 읽고 수정했는데 아직 1/3이 남았다는… 크윽…

그래도 이번 챕터만 지나가면 다음부터는 직접 코딩하면서 만드는 과정이기 때문에, 이렇게 오래 걸리진 않을 꺼라 생각합니다. (사실 이거 하나 보고 계속 달리고 있는 중입니다. ㅠㅠ 도중에 몇번이나 목차에서 챕터를 날리고 싶은 충동이 밀려와서… ㅠㅠ)

아흑… 또 시간이 이렇게 흘렀군요. 언능 자고 내일도 최대한 빨리 와서 마무리 해야겠습니다. 에궁… 진짜 이건 아닌데… ㅠㅠ

그럼 다들 좋은 밤 되시길 ;)

이번 주말은 좀 특별해서 시간이 많이 날 줄 알았는데, 결혼식이다 뭐다 하는 바람에 결국 시간에 쫓기고 말았습니다. ㅠㅠ 주말에 해야지 하면서 잡았던 스케줄은 엉망이 됐습니다. 이궁…

결국 이렇게 되면 또 평일에 번개같이 집으로 달려와서 이것 저것 하는 수 밖에 없는데… 어쩔 수 없군요. 이번 주도 미친듯이 집으로 달려와야겠습니다. @0@)-b 물론 며칠이나 가능할지는 두고 봐야 알겠지만 말입니다. ㅎㅎ

요즘 계속 글 쓰는게 어렵다는 생각을 합니다. 예전부터 느끼고 있던 거였지만, 요즘 들어 쓰는데 시간을 많이 투자하다보니 더 깊이 와 닿습니다. 정말 무슨 책이라도 한권 봐야할까요? ㅠㅠ 이럴 줄 알았으면 책이라도 왕창 읽어 놓는건데… 한참을 쓰다 보면 내가 무슨 말을 하고 싶은 건지 잊어 먹는 경우도 종종 있고, 적당한 어휘가 떠오르지 않아 한참을 고민하는 경우도 많습니다. 아무래도 국어가 따리는거 같네요. ㅠㅠ

아흑… 계속 쓰다보면 좀 나아지려나… 글짓기에 소질이 없어서 그런가보다 하고는 있는데, 무지 힘들군요. ㅎㅎ 그래도 시작한 일이니 계속 해야겠지요. ;) 일단 열심히 해볼 생각입니다. @0@)-b 홧팅~!!!

헛… 벌써 시간이 이렇게… 이만 자야겠습니다. 다들 좋은 밤 되세요~ ;)

ps) elf64 관련 문서는… 결국 주중에 업데이트 해야겠네요. ㅠㅠ)-b 아흑…

소프트웨어 멤버십에서 활동할 때 자료 남기는 습관이 든 이후로,  뭘 했다 하면 주절 주절 적어 놓는 게 버릇이 됬습니다. 메모장은 보통 회사 밖에서는 스프링노트(http://kkamagui.tistory.com)을 많이 쓰고, 요즘은 회사 때문에 미투데이(http://www.me2day.net/kkamagui)를 씁니다. 회사에서는 블로깅하기도 힘들 뿐더러, 회사가 보안이 나름 엄격한지라 외부로 뭘 보내면 의심을 받거든요. ^^;;;;

요즘 OS를 만드는 내용에 대해서 정리를 하고 있는데, 초반 설치부터 GUI 애플리케이션까지 모든 과정을 다 다루려고 하니 쓸게 한두가지가 아니더군요. 쩝쩝 힘듭니다. ㅠㅠ 오늘은 GCC 소스를 이용해서 크로스 컴파일러를 만드는 내용을 좀 적어 봤는데, 예전에 블로그에 남긴 글을 참고하면서 썼습니다. 정말 간단한 메모만 남겼는데 그것 때문에 훨씬 수월하게 끝낼 수 있었습니다. 처음에 크로스 컴파일할 때는 옵션부터 시작해서 빌드 순서까지 수많은 시행착오를 거치며 며칠 동안 했었는데, 오늘은 1시간도 안 걸려서 끝나더군요. ㅠㅠ)-b GCC 소스를 통해 크로스 컴파일러를 만드는 방법은 http://kkamagui.tistory.com/507 에서 볼 수 있습니다.

아흑... 정리란 역시 좋은 것이군요. 이게 없었더라면 주말 다 날릴 뻔 했습니다. ㅠㅠ 얼마나 다행인지... ㅎㅎ 앞으로도 계속 열심히 남겨야겠습니다.

메모 쵝오 >ㅁ<)-b

ps) 그러고보니 스프링노트에 elf64 파일 포맷 재배치하는 방법에 대한 글을 쓰다 말았는데, 언능 마무리해서 포스팅해야겠군요. (근데 볼 사람이 있을라나… ㅡ_ㅡa..)

이거 원… 오늘 메타 블로그 사이트에 들어갔다가 고전 게임인 테트리스에 저작권이 걸려있다는 글을 봤습니다. 몇 해전에 그 많던 온라인 테트리스 게임이 사라진 이유도 저작권 계약을 하지 못해서였다네요.

이런… OS에 응용 프로그램으로 테트리스 만드는 걸 하려고 했는데, 다른 게임으로 대체해야겠습니다. ㅠㅠ 이거 원 만들어 놓고도 못쓰니 살짝 답답하군요. 끄응... 그럼 당체 무슨 게임을 만들어야… ㅠㅠ 퍼즐 맞추기 같은 거는 저작권이 없을라나... 아님 피자 먹는 스네이크 게임이라도... ㅠㅠ

혹시 이런 게임이 들어갔으면 좋겠다고 생각하시는 게 있으시면 댓글로 제보 부탁 드립니다. 최대한 반영해서 OS에 넣도록 할테니, 괜찮다고 생각하시는 게 있으시면 바로 댓글 주세요 ;)  정 안되면 퍼즐 맞추기라도 해야... ㅠㅠ

그럼 다들 좋은 밤 되세요~ ;)

아유… 요즘 OS를 대충 만들어 놓은 거에 대해서 글을 좀 적고 있습니다. 글 재주가 워낙 없는지라 진도가 무지 안 나가는군요. 쩝쩝… 특히 앞부분은 기술적인 내용보다는 소설(??)에 가까운 내용들이라 더 진도가 안 나가는 것 같습니다. ㅡ_ㅡa... 그렇다고 안 쓸 수도 없는 일이니… 쿨럭;;;

겨우 겨우 서론 부분을 끝내 놓고 나니 이번에는 환경 구축이 문제로군요. GCC와 NASM을 사용해서 개발했기 때문에 이 두 가지만 설치 가능하면 이론상(?) 어디서든 OS를 개발할 수 있습니다. 물론 GCC가 64Bit 빌드 옵션을 지원하지 않으면 크로스 컴파일러를 만들어야 하는 부분이 추가되긴 하지만... 이러한 수고로움 정도야 OS를 개발하는데 드는 시간과 노력에 비하면 아무것도 아니지요. ㅎㅎ

아아~ 이것 참... 그냥 윈도우에서 개발하는 걸로 못 박기는 그렇고... 이것 저것 차이를 들어서 적자니 귀차니즘이 도지는군요. ㅠㅠ 이 일을 어찌해야... 뭘 정리하는 게 쉬운 일이 아닌 것 같습니다.

크으... 일단 오늘은 이만하고 내일 다시 해야겠습니다. 창작의 고통 + 잠이 몰려와서 죽을 것 같군요. ㅎㅎ

다들 좋은 밤 되세요 >ㅁ<)-b

오늘 간만에 글을 좀 썼습니다. 사실 썼다는 표현보다는 쓰고 있다는 표현이 더 맞는 것 같습니다만… ㅎㅎ  역시나 진도가 안나가는군요. 마이크로소프트웨어 기고할 때도 그랬는데, 역시 서문이 가장 어려운 것 같습니다.

저 같은 경우 본문은 소스 코드 설명이나 현상 설명 같은 내용들을 주로 넣으니 굳이 작문을 할 필요가 없는데, 서문 같은 경우는 그런 내용이 아니라 좀 가벼운 내용들 + 잡설 위주로 쓰는 편이라 상당한 고통이 따릅니다. 말 그대로 “작문”을 해야하니… 말 주변이 없는 저로서는 출산의 고통(?)과 맞먹는군요. ㅠㅠ 끄응… 그래도 넘어야 할 산이니만큼 꾸역꾸역 써야겠지요. ㅠㅠ

아래는 2004년 경에 만든 32Bit OS의 GUI 시스템 화면입니다. 내용물을 비교하자면, 지금 것과 비교하면 완전 최악이지만 GUI 시스템은 그리 크게 바뀌지 않은 것 같습니다. 그때도 상당히 고민했었는데… 지금 생각하니 그 당시는 너무 몰랐기 때문에 복잡하게 구현할 수 밖에 없었던 것 같습니다. 지금 코드는 훨씬 간단한데 말이지요. ㅎㅎ

 

마치 배경처럼 나와 있는 저 까마귀 그림은 제가 손수 그림판으로 그린 거라는… 지금 생각하니 저것도 웃기는 군요. 왜 저걸 그리고 있었을까나… ㅎㅎ 이궁…

에혀~ 밤이 깊었으니 자야겠습니다. 오늘은 좀 일찍 자는군요. ㅎㅎ 내일은 좀 더 일찍자야겠습니다. ;)

 에구에구... 오늘 교육 끝나고 집으로 쏜살같이 달려와서는 그 동안 마음에 걸렸던 부분들을 수정했습니다. 사실 더이상 손대기에는 시간도 부족하고, 목표로 정한 것이 있어서 더이상 구현만 할 수는 없었다는... ㅠㅠ 그래서 완성도는 약간 떨어지지만, 프로토타입을 완료했습니다. ㅎㅎ

 지금까지 진행된 것은 멀티 태스킹 + 파일 시스템 + 동적 메모리 관리 + GUI 시스템 + 기타 시리얼, 마우스, 하드 디스크 드라이버 등등 정도 입니다. 뭐 많이 하긴했는데, 적어놓고보니 별거 없군요. ㅠㅠ 아래는 1.0 버전의 스크린샷입니다.

 파일 시스템이 추가되어서 시리얼로 실행파일을 매번 전송해서 실행하는 번거로움이 없어졌습니다. "Application Pannel"에서 "GUI Shell"을 실행한 다음 루트 디렉토리에 있는 테트리스 실행파일을 load 명령으로 실행하면 테트리스가 실행됩니다. ^^)-b GUI 쉘은 화면을 지우는 cls 명령과 디렉토리를 표시하는 dir 또는 ls 명령만 가지고 있습니다. 

 기념삼아 프로토타입을 테스트할 수 있는 파일을 올립니다. 아래 파일을 다운 받으셔서 압축을 푸신 다음 "qemu64MyOs.bat" 파일을 실행하시면 됩니다. 


 아아~ 오늘도 늦게까지 작업했더니 피곤합니다. ㅠㅠ. 일찍 끝낼 수 있었는데 QEMU가 Single Core 모드로 동작할때 IOAPIC 쪽을 사용하지 않는 걸 몰라서 한참 삽질했습니다. ㅡ_ㅡa... 커널이 잘못된 줄 알고 2시간동안 갈아 엎었습니다. 디버그 코드 덕에 겨우 알았다는... 싱글 코어일때는 PIC를 그대로 쓰도록 바꿔놔야겠군요. ㅎㅎ

 이크~ 저는 이만 자야겠습니다. 다들 좋은 밤 되세요~ ㅎㅎ

 

 
 이번주는 결혼식이다 뭐다해서 그렇게 많은 시간을 투자하지 못했습니다만, 막판 스퍼트해서  파일시스템을 추가하는데 성공했습니다. >ㅁ<)-b 사실 대부분의 코드는 윈도우 환경에서 시뮬레이션하면서 검증했기 때문에, 그냥 컨트롤 C+V 신공으로 끝냈습니다. ㅎㅎ

 그리고 내친김에 GUI 쉘에 dir 기능도 추가했습니다. GUI 쉘을 만든지는 좀 됬지만 귀찮아서 그냥 뒀는데, 점점 불편함이 커지더군요. 쉘 기능이 필요할때는 콘솔 모드 커널로 빌드해서 쉘을 쓰다가 다시 GUI 테스트할때는 윈도우 모드로 빌드해서 부팅하고... 이걸 수백번 정도 반복하다보니 그냥 만드는게 편하겠다는 생각이 들었습니다. 그래서 뚝딱~!!! 만들었습니다(사실 이 일이 더 많이 걸렸다는... ㅠㅠ).

 아래는 GUI 쉘로 루트 폴더와 이미지 폴더를 본 화면입니다. 깔끔하게 잘 나오는 걸 볼 수 있습니다. ㅎㅎ (이미지 윈도우는 /image/image0.img 파일을 읽어서 화면에 표시하도록 수정되었습니다)

 이거 뭐 점점 기능이 추가될수록 갈아 엎는 코드의 양도 많아지는군요. 이번에도 몇군데나 갈아 엎었습니다. ㅠㅠ 처음에는 간단한 OS를 만들자는 생각이었는데, 욕심이 자꾸 생겨서 이것도 추가하고 저것도 추가하게 되네요. 이렇다 언제 거사(?)를 시작하게 될지... ㅡ_ㅡa...

 진짜 내일 동적 메모리 할당쪽 알고리즘만 좀 더 수정하고, 거사를 시작해야겠습니다. 고칠게 있으면 거사를 진행하면서 고치던가 해야겠군요. ㅎㅎ

 내일 교육은... 또 물건너 간 것 같습니다. 푹 자다 올듯... ㅠㅠ
 다들 좋은 밤 되시길 ;)

 오늘도 집에 오자마자 컴퓨터를 키고 열심히 파일 시스템에 캐시를 추가하는 작업을 했습니다. 일단 어제 고민했던 문제 중에 FAT 영역 즉 클러스터 맵이 있는 영역에서 이상하게 캐시 히트가 낮게 나오는 문제를 뒤져봤는데... 역시나 문제가 있더군요. ㅎㅎ

 클러스터를 할당하는 코드가 클러스터 맵의 첫번째부터 마지막까지 검색하며 빈 클러스터를 찾게 되어있는데, 이런 경우 하드에 용량이 어느정도 차게되면 앞부분은 이미 대부분의 클러스터가 할당되어있음에도 불구하고 우직하게(?) 검색합니다. 따라서 클러스터 맵 영역의 캐시 또한 순차적으로 플러시되면서 거의 재사용되지 못하고 버려지게 되더군요.

 위와 같은 문제가 있어서 마지막으로 할당한 클러스터가 있는 클러스터 맵 인덱스를 저장하고, 클러스터 할당 요청이 올 때마다 가장 마지막으로 클러스터를 할당해준 클러스터 맵부터 검색을 시작하도록 수정했습니다. 이렇게 하니 거의 대부분 마지막으로 할당한 클러스터 맵에서 할당되서 거의 90%에 해당하는 캐시 히트가 나오더군요. 클러스터 맵을 쓰는 경우는 클러스터 할당/해제의 특성상 클러스터를 할당하려면 해당 맵을 읽어서 검색한 후, 할당했다고 마크를 해야하기 때문에 쓰는 경우는 100% 가 나왔습니다. 실로 엄청난 결과~!!! 이걸 실제 HDD에 적용할 경우 10번당 1번 하드를 읽는 것과 마찬가지기 때문에 시간을 엄청나게 절약할 수 있을 것 같습니다. >ㅁ<)-b

 하지만 이 기쁨도 잠시... 클러스터 영역을 캐시하는 기능도 추가했는데, 캐시 히트가... 20% 정도... ㅠㅠ 캐시 블럭의 개수를 128개 정도로 설정한 상태인데, 이를 더 늘리면 히트는 올라가겠지만 메모리 소모가 늘어나는 문제가 있기에 적당히 타협을 해야할 것 같습니다. 테스트 환경에서 캐시 블럭의 수를 2048개까지 늘리니까 40%까지는 히트가 올라가던데, 메모리 소모에 비해서 히트의 상승폭이 좀 낮아서 일단 다시 낮춰 놨습니다. 테스트는 가상으로 파일 3개를 만들고 랜덤한 파일 오프셋에서 랜덤한 사이즈를 읽고 쓰도록 하는 방법으로 하고 있는데, 아무래도 랜덤하게 읽고 쓰다보니 같은 클러스터가 다시 쓰이는 경우가 적은 것도 하나의 이유인 듯 합니다. 좀 더 고민해보고 캐시 블럭의 개수를 결정해야겠습니다. >ㅁ<)-b

 뭐든 구현하고 테스트할 때가 제일 재미있는 것 같습니다. 특히나 오늘처럼 예상하지 못한 결과가 나왔을 때는 더 즐겁습니다. 하핫~!!!
 헛.. 글고보니 내일은 고향에 가야되는데... 또 이렇게 시간이... ㅠㅠ 그만 자야겠습니다
 다들 좋은 밤 되세요. >ㅁ<)/~~


 어이쿠 또 시간이 이렇게나 흘렀군요. ㅠㅠ 방금 파일 시스템에 FAT(File Allocation Table) 영역에 해당하는 부분에 캐시 버퍼를 추가했는데, 대충 캐시 히트률이 60% 정도 나왔습니다. 생각보다 좀 저조한듯 하기도 하고... 일단 Sequential Write를 랜덤하게 돌려서 쓰고 읽고 검증하는 테스트를 돌리고 있는데, 에러가 안나오는거 보면 큰 문제는 없는 것 같습니다. 약간 문제라면... 캐시 히트률이 좀 낮은 게 문제라면 문제랄까요? ^^;;;;

 일단 캐시 알고리즘은 LRU(Least Recently Used)을 선택했고, Dirty 비트를 추가해서 Dirty 또는 Clean 중에 왠만하면 Clean인 놈을 선택하도록 했습니다. 물론 단순히 Age 만을 비교하는 것도 괜찮지만, 만약 쓰기가 수행된 캐시 버퍼 즉 Dirty 비트가 켜진 캐시 버퍼를 선택하게 되면 하드에 한번 더 써야하는 문제가 발생할 수 있어서 Clean을 우선적으로 선택하게 만들었습니다. Clean 인 놈은 쓰기가 수행되지 않고 읽기만 수행된 버퍼기 때문에 플러쉬(캐쉬에서 내보낼때)할 때 HDD에 안써도 되기 때문이지요. ㅎㅎ

 아흑... 원래는 더 일찍 끝났어야 하는데, lseek를 추가한다고 시간이 이렇게 흘러버렸군요. 처음에 예상했던 크기보다 점점 커지고 있어서 살짝 걱정이 됩니다. 어휴... 이걸 어떻게 해야될지... ㅠㅠ 그래도 일단 하던 작업은 끝내는게 맞는 듯 하니 이것까지만 해야겠습니다. ^^;;;

 내일은 알고리즘을 좀 손보고 데이터가 있는 클러스터 영역을 캐싱하는 기능도 추가해야겠습니다. 그리고 OS에 바로 옮겨봐야겠군요. ㅎㅎ 살짝 기대가 된다는... 과연 캐시를 사용하는 것과 사용하지 않는 것이 가상 머신에서 어떻게 차이가날지... 완전 기대됩니다. ㅎㅎㅎ

 그럼 내일 출근을 위해 전 이만 취침하러... ㅎㅎ
 다들 좋은 밤 되시길~ ;)


 주말 동안 쉬엄 쉬엄 파일 시스템을 설계했습니다. FAT 파일 시스템처럼 클러스터의 링크 형태로 말이지요. ^^ 최대한 간단하게 구현하려고 디렉토리 구조는 더욱 더 단순화시켰습니다. 그리고 코딩에 들어갔는데, 구현 초기에는 쉽게 쉽게 끝나는가 싶더니... 결국 또 복잡해지더군요.

 일단 멀티 태스크나 멀티 코어 환경에서 동기화 문제는 고려하지 않고, 단순히 파일 및 디렉토리 관련 API 만 만드는데, 꼬박 이틀이 걸렸습니다. 사실 API는 간단하게 만들고, 응용 프로그램이 잘 알아서 쓰도록하면 정말 간단한 구조를 유지할 수 있는데... 욕심이 생기다보니 이것 저것 많이 만들었습니다. 끄응.... ㅡ_ㅡa...

 덕분에 쓰기는 편해졌습니다만... 설명할게 많아져서 고민입니다. 현재 opendir, readdir, rewinddir, closedir, openfile, readfile, writefile, closefile, rewindfile, createfile, deletefile, createdirectory, deletedirectory까지 만들어져 있는데, 소스가 장난이 아니네요. 클러스터를 걸치는 녀석들 읽는거 처리하랴, Path 관련 처리하랴... 어휴... ㅠㅠ 하는 김에 rewindfile은 좀 더 고민해서 lseek로 만들어야겠습니다. 원래 lseek는 고려하지 않았지만... 만들다 보니 lseek 빼고는 다 만들었군요. ㅡ_ㅡa...

 만들긴 했는데... 과연 이 API가 얼마나 사용될지.... 삽질한건 아닌가 걱정이됩니다. ㅠㅠ
 억... 또 벌써 시간이 이렇게 됬군요.

 다들 좋은 밤 되시길.... ^^)-b

 ps) 아흑... 파일 동기화 문제는 또 어떻게 해결하지... ㅠㅠ


 아이쿠... 원래 계획은 좀 더 진도를 나가는 거였는데... 그 동안 무리를 좀 했더니 저녁에 잠깐 졸았습니다. 한 40분 잤으니 존거 치고는 시간이 좀 길군요. ^^;;;; 아무리 피곤해도 존적은 별로 없는데... 몸이 좀 피곤하긴 한가 봅니다. 그러거나 말거나 할꺼는 해야하니 세수 한판하고 또 진도 나갔습니다.

 일단 어제 대충 만든 테트리스를 좀 수정해서 블럭 색깔하고, 내부 알고리즘을 좀 정리했습니다. 원래 테트리스가 그리 복잡한 알고리즘이 필요없는 게임이라... 알고리즘이라는 말을 쓰기도 부끄럽습니다만... ㅡ_ㅡa... 발로 짜다보니 도저히 안되겠더군요. ㅎㅎ 내일쯤 정리되면 한번 올리겠습니다. ^^;;;;

 테트리스를 수정한 뒤에 한참을 고민했습니다. 이제 더 뭘 구현해야 하는가.... 가만히 보니 3개 정도가 더 남았더군요. 디지털 시계, 텍스트 뷰어, 이미지 뷰어 정도 남았던데... 디지털 시계는 텍스트로 날짜와 시간만 표시해줄 생각이니 크게 어렵지는 않을 것 같고... 텍스트 뷰어는 말 그대로 뷰어니까 그냥 텍스트만 출력해주면되니 이것도 별로 어렵지 않을 것 같았습니다.

 그렇다면 남은 것은 이미지 뷰어인데, 어떤 파일 포맷을 사용할 것인가가 문제더군요. 가장 쉽게 처리할 수 있는게 BMP 파일 형식인데... BMP도 다양한 버전이 있기 때문에 어떤걸 해야할지 고민이 됬습니다. 그러다가 문득 NDS 홈브루를 개발할때 만들었던 KNG(kkamagui NDS Graphic) 파일 포맷이 생각나서 그걸 사용하기로 했습니다. NDS 홈브루도 16bit Color로 설정되어있고, 마침 지금 만드는 OS도 16bit Color로 설정되어있으니 큰 수정없이 사용할 수 있을 것 같았습니다. KNG를 사용하는 NDS 홈브루는 http://kkamagui.tistory.com/49http://kkamagui.tistory.com/468 에서 보실 수 있습니다.


 위의 화면은 수정된 테트리스와 그 뒤로 이미지 뷰어가 실행된 화면입니다. 이미지는 KNG로 변환해서 OS에 시리얼로 전송하는 방식으로 했습니다. KNG를 사용한 덕분에 작업이 상당히 빨리 끝났습니다. ^^;;; 이것 저것 많이 만들다보니 이런 날도 오는군요~ 좋구로 ㅎㅎ

 작업을 진행하면서 느끼는 QEMU의 장점은 TCPIP로 가상 시리얼을 연결할 수 있어서 굉장히 편리하게 시리얼 통신을 할 수 있는 점입니다. 속도도 굉장히 빠르고 QEMU 내부적으로 버퍼 관리도 해주니 OS에서 구현된 허접한 시리얼 드라이버로도 잘 됩니다. 덕분에 귀찮은 작업이 얼마나 줄었는지... ㅠㅠ)-b QEMU 만세~!!!

 아아... 벌써 또 시간이 이렇게 됬군요. ㅠㅠ 언제쯤 일찍 자려나... 그러려면 집에 굉징히 일찍오던지... 아니면 컴퓨터를 안켜야하는데, 둘다 실현 가능성이 낮군요. ㅠㅠ 거의 다 완료될때까지 잠을 줄이는 수 밖에는 없을 것 같습니다. 아흑....

 그럼 다들 좋은 밤 되세요. ^^)/~

ps) 헛... 이런 잠결에 만들다보니 화면에 있는 이미지 뷰어에 스펠링이 틀렸군요. 이런 ㅠㅠ

 헉헉... 아이구 머리야... 예전에 만든 소스를 긁어다 붙이는 것도 힘들군요. ㅎㅎ 금방 끝날줄 알았는데... 벌써 시간이 이렇게... 일단 아래는 실행한 화면입니다. 아직 프로토타입의 형태라서 버그도 좀 있고, 상태도 별로 안좋습니다. ㅎㅎ


 자세한 내용은 내일 올리겠습니다. 좀 늦어서... ㅠㅠ)-b
 그럼 다들 좋은 밤 되세요 >ㅁ<)-b



 이제까지 GUI 어플리케이션은 모두 커널레벨에서 동작하는 커널 스레드와 같은 개념이었습니다. 즉 커널 코드에 포함되어있으며, 스택만 별도로 사용하는 존재였지요. ^^;;; 그래서 "어플리케이션"이라고 확실히 부를 수 있는 유저 레벨 태스크를 이용해서 GUI 어플리케이션을 만들어봤습니다.

 위의 화면에서 좌측 상단에 보이는 User Level Application이라고 표시된 윈도우가 유저 레벨에서 동작하는 GUI 어플리케이션입니다. OS 코드가 아주 간단하지만, 현대 OS가 갖추고 있는건 쪼금 쪼금씩 구현해 놓은지라, 당연히 커널 영역에는 접근하지 못하고 시스템콜(System Call)을 통해서만 커널 함수를 쓸 수 있습니다. 다만 아직 GUI 관련 시스템콜이 그리 많지 않아서 덩그러니 윈도우 기본 화면만 표시하고 있다는... ㅠㅠ 원래는 Hello, World를 찍어야하는데 시스템 콜을 만드는게 귀찮아서 그냥 뒀습니다. ㅠㅠ 너무 늦게 퇴근해서... ㅠㅠ

 그리고 유저 레벨 프로그램은 역시 커널과 별도로 빌드해서 실행하는게 제 맛이기 때문에, 별도로 elf 파일을 생성했고 지난번에 만든 File Downloader를 통해 OS에 전송했습니다. OS에는 당연히 윈도우 버전의 File Downloader를 만들었구요. ㅎㅎ 위의 화면에서 가운데 있는 것이 윈도우 버전의 File Downloader 입니다. Memory Monitor의 그라데이션 태스크 바를 그대로 썼습니다. ㅎㅎ 그러고보니 스프링노트에 ELF 재배치에 대한 글을 적어놨었는데, 깜빡했군요. 언능 마무리해서 포스팅해야겠습니다. ㅎㅎ

 시간이 지날수록 점점 커지는 걸 보니 흐믓합니다. ^^ 이제 조금만 더하면 되겠군요. ㅎㅎ 내일은 좀 일찍오면 테트리스를 만들어 올려봐야겠습니다. 그리고 가능하면 텍스트 뷰어나 BMP 뷰어같은 것도 만들어봐야겠네요. ㅎㅎ

 어이쿠 벌써 이렇게 시간이.... 전 이만 자러가야겠습니다.
 다들 좋은 밤 되세요 ^^)/~



 헥헥... 추석 이후에 전주 칼퇴를 목표로 열심히 일찍 퇴근했더니만, 이번주는 꽤 많은 시간을 투자할 수 있었습니다. 덕분에 고민도 많이 했고, 기능도 여럿 추가했습니다. 일단 아래 스크린샷 먼저 보시죠. ^^)/~

 가장 큰 변화는 어플리케이션 패널(Application Pannel)을 추가해서 굳이 GUI Shell을 통하지 않고서도 프로그램을 실행할 수 있게 한 것과, CPU 및 메모리 상황을 표시하는 어플리케이션이 추가된 것입니다.

 어플리케이션 패널은 마우스가 위치했을 때 해당 항목을 붉은 색으로 바뀌게 하여 사용자로 하여금 알기 쉽게 한 것이 포인트입니다. 제가 원래 GUI쪽은 거의 신경을 안쓰는 편인데... 이번은 저 혼자만 볼게 아니라서 신경을 좀 썼습니다.

 CPU 모니터는 일정 시간동안 CPU 부하 및 현재 대기중인 태스크의 수를 표시하도록 되어있습니다. 숫자만 덩그러니 표시하는 건 좀 없어보여서 아래에 그래프도 같이 표시하도록 했습니다.

 메모리 모니터도 CPU 모니터와 비슷한 방식이지만, 좀 다른 점은 아래에 사용량 그래프에 그라데이션 처리가 되어있는 점이랄까요? ㅎㅎ 메모리 사용량이 높아지면 게이지가 점점 올라가면서 붉은 색 계통으로 바뀝니다. 굳이 그럴 필요 없지만... 왠지 뭔가 변화를 줘야할 듯 해서.... 나름 많이 신경썼습니다. ㅡ_ㅡV...

 그외 소소한 변화는... 타이틀 바를 좀 더 진하게 한 것과, GUI쪽에 일부 최적화를 수행한 것 정도입니다. 크게 눈에 보이지는 않지만, 화면을 그리는 속도가 약간(??) 더 빨라졌습니다. ^^  와우~!!!

 아참~ 가운데 보이는 시커먼 화면은 방금 추가된 따끈 따끈한 GUI Shell 입니다. 알맹이는 Console꺼를 그대로 쓰면 되기 때문에, 화면만 먼저 만들었습니다. 처음에는 검은 바탕에 하얀 글씨였는데, 맨 처음 만들었던 32bit OS 생각이 나서 검은색 바탕에 녹색(메트릭스 스타일??)로 바꿨습니다. 한때 선망의 대상이던 모노크롬 모니터처럼 말이지요. ^^;;;;

 어휴~ 만들다보니 상당히 많이 왔습니다. 이제 파일 다운로더 프로그램과 테트리스 정도 만들고 거사(?)를 시작할 생각입니다. 이 정도면 남에게 보여줘도 부끄럽지 않을 것 같으니 말이지요. ㅎㅎ 그나저나 70KByte도 안되는 크기로 참 많은 일을 할 수 있군요. 예전에는 몰랐는데 말입니다. ;) ㅎㅎ

 아래는 지금까지 작업한 내용을 실행해 볼 수 있는 파일입니다. 예전과 마찬가지로 qemu64MyOs.bat 를 실행하시면 됩니다.


 일단 밥 좀 먹고 다시 작업을 해야겠군요. ㅎㅎ
 그럼 다들 좋은 하루 되세요 ^^)/~~~


ps) X 버튼을 눌렀을때 윈도우 및 태스크를 종료하는 기능을 추가했습니다. 그 동안 귀차니즘으로 안했었는데... 더이상 미룰 이유가 별로 없더군요. ㅎㅎ 첨부파일은 최신으로 새로 올렸습니다. ^^)/~

 간단히 시작한 일인데... 버그가 나오는 바람에 연짱 7시간 정도 디버깅한 것 같습니다. ^^;;; 멀티 코어라는걸 자꾸 까먹고 작업을 하다보니 이상한 고정관념에 사로잡혀서 제대로 코딩을 안했더군요. ㅠㅠ)-b 크윽... 오늘은 꼭 기억할껍니다. ㅠㅠ 이렇게 허접할수가...

 멀티 코어임에도 불구하고 CPU가 초기화되는 순서가 0번부터 순차적일꺼라는 말도 안되는 생각을 계속 하고 있었습니다. 그래서 코딩도 순차적으로 CPU가 초기화 되니 스택도 순차적으로 할당해 주도록 했더군요. 허나 실상은... 초기화 되는 순서를 아무도 모른다는... ㅠㅠ 그래서 CPU의 ID를 직접보도록 수정했습니다. 끄응... ㅡ_ㅡa...

 그리고 막판에 짬을 좀 내서 CPU Monitoring Application을 추가했습니다. 원래 이게 목적이었는데, 장난삼아 Dual Core에서 Quad Core로 QEMU 옵션을 변경했다가 버그를 발견하고 디버깅만 주구장창했다는... 내일 출근은 또 어찌할지... 머리도 띵하고... 흑흑....

 아래는 급히 찍은 스크린샷입니다. Quad Core로 만들어 놓고 실행시킨 화면인데, 원체 허접하게 CPU Load를 계산하는지라... 별로 믿음직스럽지 못하군요. ㅎㅎ 그래도 된다는데 의의를... ^^;;; 시험삼에 Hexa Core(16개)까지 QEMU에서 테스트해봤는데, PC도 버벅거리고 QEMU에서 속도가 제대로 안나오더군요. 그나마 Quad Core까지는 쓸만한 것 같습니다.
사용자 삽입 이미지

 어휴... 테스트를 제대로 안해보고 거사를 시작했다면 어찌됬을까 아찔합니다. ㅠㅠ 역시 여유를 갖고 검토하는 시간을 갖길 잘한 듯 합니다. 에혀~

 이제 자야겠군요. 내일 하루종일 좀비모드로 지낼 것 같다는... ㅠㅠ
 다들 좋은 밤 되세요 ;)


 다들 즐거운 추석 연휴를 보내시고 계신가요? ㅎㅎ 저는 할머니댁에 당일치기로 갔다오는 바람에 시간이 많이 남아서 오늘도 어김없이 OS를 만들고 있습니다. 이런 걸 보면 역시 프로그래머가 천직인 것 같네요. ㅎㅎ ^^;;; 다만 좀 아쉬운 점이 있다면 마제스터치 키보드와 함께하지 못하고 허접한 삼성 멤브레인 키보드를 치고있다는 것... 기계식 키보드를 치다가 멤브레인 키보드를 치니 끝까지 눌렸는지를 확실히 알 수 없군요. ㅡ_ㅡa... 오타 작렬입니다. ㅠㅠ

 잡담은 이쯤하고... OS 개발도 거의 막바지로 가고 있어서 그 동안 고민했던 것들을 하나, 둘 마무리하고 있습니다. 옛날부터 OS를 몇번이나 뒤엎고 다시 들고 있지만, FPU 즉 실수 연산에 대해서는 그리 깊게 고민하지 않았습니다. 왜냐하면 finit, fxrstor, fxsave와 같은 멋진 어셈블리어 명령어들이 x387 Coprocessor의 상태를 관리해줬기 때문이지요. 그때는 단순히 이 명령들만 호출하면 된다고 생각했습니다. ^^;;

 그런데 막상 해보니 실상은 좀 다르더군요. ㅡ_ㅡa... fxsave 및 fxrstore를 이용해서 FPU 상태를 저장/복원했을 때 사용되는 메모리의 크기는 총 512Byte 입니다. 이건 상당히 큰 사이즈입니다. @0@)/~!!! 이것을 만약 Task Switching 시마다 저장/복원을 한다고 가정하면 Core에 있는 Register를 저장/복원하는 크기보다 더 크기때문에 거의 2배 정도의 Context Switching 시간이 걸립니다. ㅡ_ㅡa... 무시무시한 시간이지요.

 요 며칠동안 고민을 많이 했었는데, 가만히 생각해보니 뭔가 답이 나오더군요. Task 중에 FPU를 사용하는 Task가 여러개 있다고 가정하면, 인코딩 프로그램과 같은 프로그램을 제외하고는 실수 연산이 그리 빈번하지 않습니다. 즉 Task의 전체 코드에 비해 FPU 연산이 차지하는 비중이 작다는 것이지요. 그리고 또 한가지 포인트는 모든 Task가 FPU를 사용하는 것은 아니라는 겁니다. 경우에 따라 정수 연산으로도 충분한 Task가 있으니까요. ^^

 그래서 OS에서 마지막으로 FPU 연산(mmx, sse, sse2, sse3관련 어셈블리어 명령 사용)을 사용한 Task를 저장하고 있다가, 어떤 Task가 FPU 연산을 수행하면 마지막으로 사용한 Task와 비교해서 처리하는 방식을 생각했습니다. 사실 이 방법은 INTEL 문서(Volume 3)에도 나와있는 방법입니다. ^^;;; CR0 레지스터의 TS bit를 잘 사용하면 FPU 연산이 발생할때마다 7번 Exception이 발생하게 할 수 있고, 이것을 이용해서 처리하도록 가이드가 나와있습니다.

 제가  사용한 간략한 알고리즘은 아래와 같습니다.
  • FPU 연산이 발생했을 때, 마지막으로 FPU를 사용한 Task가 있는지 확인한다.
  • 마지막으로 FPU를 사용한 Task가 현재 Task이면 아무것도 해줄 필요 없다.
  • 마지막으로 FPU를 사용한 Task가 현재 Task가 아니면 마지막으로 사용한 Task에 FPU의 상태를 저장한다(fxsave).
  • 현재 Task가 FPU를 사용한 적이 없으면 FPU 상태를 초기 상태로 설정한다(finit).
  • 현재 Task가 FPU를 사용한 적이 있으면 Task에서 FPU 상태를 복원한다(fxrstor).
  • FPU를 마지막으로 사용한 Task 정보를 현재 Task로 설정한다.

 위와 같은 방식으로 총 300개의 FPU Task를 생성해서 돌려봤습니다. 처음에 FPU 상태를 저장하지 않았을때는 FPU가 여기저기 Task에서 건드려져서 정상적으로 계산 결과가 나오지 않더군요. 하지만 위와 같은 알고리즘으로 구현하고나니 계산 결과가 정확하게 나왔습니다. >ㅁ<)-b

 이렇게 또 한고비가 넘어가니 기분이 좋습니다. ㅎㅎ 잠깐 나갔다 와서 다른 장난(?)도 좀 쳐봐야겠군요. ㅎㅎ
 다들 즐거운 연휴 보내세요. ^^)-b



 

+ Recent posts