<현재 진행 중인 GUI 시스템의 화면> 

추석 연휴 때부터 이것 저것 일이 많아서 미친 듯이 달려왔더니 이제야 블로그에 한자 적어 올립니다. ㅠㅠ 아흑... 요즘 회사에서도 신경 쓸게 많다 보니 점점 작업시간이 줄어들어서 이러다가 큰일(?)나게 생겼네요 ㅠㅠ. 그래도 작업은 해야 하는지라 아침에 좀 무리해서 진행하고 있습니다(이러다 쓰러지는 게 아닌가 모르겠군요. 쿨럭..;;;)

그동안 아주 쉬운 알고리즘을 사용해서 GUI 시스템 작업을 했는데... 이제야 어느 정도 모양이 나와서 올려봅니다. ^^;;; 이제 조금만 더 있으면 바이너리 정도는 공개할 수 있는 퀄러티가 나오겠군요. 일단 윈도우 생성, 닫기, 선택/선택 해제, 이동 정도 구현된 상태입니다. 크기 변경이랑 화면을 좀더 효율적으로 그리는 부분은 좀더 진행되어야 할 수 있을 것 같군요. 아래는 지금까지 구현된 MINT64 OS의 구동 화면입니다. ;)


 



어휴... 이제 또 달려봐야겠네요. ㅠㅠ 다음 포스팅은 언제가 될지 모르겠지만... 조만간(?) 다시 하나 올리겠습니다.

ps) 어휴... 이것 참... 언능 해야 될 텐데... 큰일이군요. ㅠㅠ

다음주면 GUI 시스템 작업을 해야 해서, 오늘 디자이너 준에게 부탁해서 프로토타입 이미지를 받았습니다. ㅎㅎ 바탕화면과 윈도우 프레임을 조합하고 보니 예전 것보다 훨씬 깔끔하네요. ㅠㅠ 어흑... 이때까지 GUI 시스템을 만들면서 윈도우 색깔이나 모양에 신경을 쓴 적이 없었는데... 시간을 좀 들이고 나니까 훨씬 멋지군요. ㅠㅠ


아래의 첫 번째 화면은 이제 만들 GUI 시스템의 프로토타입이고 두 번째 화면은 MINT64 OS 검증용으로 잠시 만들었던 OS의 GUI 시스템 화면입니다. MINT64 OS라는 이름에 맞추어 이번에는 녹색 계열로 배색해 봤습니다.

<MINT64 OS의 GUI 시스템 프로토타입>


<예전에 만들었던 GUI 시스템의 프로토타입>

 

녹색이 생각보다 촌스러운 색(?)이어서 조금만 잘못 써도 감(?)이 확 떨어져 보이던데... 멋지게 작업해 준 디자이너 준에게 감사의 말씀을 드립니다(준영아 사랑해~!! ㅋㅋ). 디자이너 준의 노력에 보답하려면 열심히 그대로 옮겨야겠네요. ㅎㅎ


아우~ 벌써 시간이 이렇게... ㅠㅠ 혹시 보시고 뭔가 부족하다고 생각되는 부분이 있다면 댓글로 제보(?) 부탁 드립니다. ;) 아직 2주 정도 시간이 있으니까 나중에 상의해서 반영하겠습니다. ;)


ps) 참고로 이미지의 저작권은 디자이너 준에게 있습니다. ㅠㅠ 무단으로 도용하면 미워할꺼에요 ㅠㅠ

드디어 긴긴 Single Core Processor 관련 부분을 마무리하고 Multicore Processor쪽으로 들어갔습니다. 이번에는 가장 기본이 되는  MP Configuration Table을 분석하는 기능을 추가했습니다. MP Configuration Table은 BIOS에서 만드는 것으로, 코어의 개수와 인터럽트 연결에 관련된 포괄적인 정보를 담고 있습니다. ;) 아래 그림을 보는 게 더 빠를 듯...

MP Configuration Table을 분석하는 이유는 실제 Core의 개수를 찾는 것과 나중에 인터럽트를 모든 Core로 전달하기 위해서입니다. BIOS는 부팅 과정에서 부팅을 담당하는 프로세서인 BSP(Bootstrap Processor)로 PIC 컨트롤러의 인터럽트 라인을 연결하므로, AP(Application Processor)를 깨운다 해도 PIC 컨트롤러의 인터럽트는 전달되지 않습니다. ;) 전달된다 하더라도 PIC 컨트롤러는 Multicore Processor를 지원할 능력이 없으므로 오동작하겠지요. ;)

따라서 Local APIC와 I/O APIC를 이용해서 모든 Core로 전달되도록 설정해야 하는데, 이때 MP Configuration Table에 저장된 정보가 아주 중요한 역할을 합니다. 실제 메인보드 제조사는 인터럽트를 어떻게 연결했는지를 알고 있으므로, BIOS에 그 정보를 저장해 둡니다. 이 정보가 MP Configuration Table에 들어 있는 것입니다. 만약 MP Configuration Table을 사용하지 않는다면... ㅎㄷㄷ... 생각만 해도 이건... ㅠㅠ

여튼~!!! 분석하는 게 끝났으니 이제 깨워서 일 시키는(?) 일만 남았군요. ㅎㅎ 아우 진짜 죽겠습니다. 이것만 끝나면 GUI로 바로 날아갈 텐데... ㅠㅠ  좀이 쑤셔 죽겠군요. ㅎㅎ 다음 작업도 끝나는 대로 인증 샷을 올리겠습니다. 다음 인증 샷에는 쌍둥이(?)가 열심히 일을 하는 화면이 나오겠군요. ;)

그럼 다들 좋은 저녁 되세요 ;)

ps) 아래는 QEMU의 MP Configuration Table의 내용입니다. 실제 PC와는 좀 다른 모습이군요. ;)



이번에도 상당히 오랫동안 작업했습니다. 요즘은 귀차니즘이 도져서 가만히 않아서 작업하는 게 힘듭니다. 그래서 약간 진도도 처지고 의욕이 살살 꺼지고 있습니다. 그래도 갈 길이 멀기에 끙끙거리면서 작업해서 겨우 붙였군요. ;)


일단 말이 필요 없으니, 직접 한번 보시죠. ;) QEMU에서 실행해서 새 그림이 그려 진 텍스트 파일을 수신한 후, 그것을 다시 화면에 표시한 동영상입니다. 화면을 캡쳐한 것을 올려도 되지만, 동영상이 좀 더 액티브(??)하니 동영상으로 올렸습니다.


<동영상 파일을 변환하니 깨져서 그대로 올렸더니 파이어폭스에서는 제대로 안보이는 문제가 있네요. ㅠㅠ>

https://t1.daumcdn.net/cfile/tistory/13153C1B4A31337702 를 클릭하시면 다운로드 받아서 볼 수 있습니다.



파일 시스템이 생기니 이런 재미난 일도 할 수 있군요. ㅎㅎ 너무 신납니다. ;) 그러고 보니 OS의 기본 기능은 대부분이 구현되었군요. 이제 남은 건 멀티 코어를 활성화하는 부분이랑 GUI 정도인 것 같은데... 다음 이번 달과 다음 달은 꽤나 고생하겠다는 생각이 드는군요. ㅠㅠ 어흑 언능 작업해서 재미난 GUI로 가고 싶어요. ㅠㅠ 그럴려면 또 열심히 달려야겠군요. 어흑...

그러기 전에 오늘은 일단 좀 쉬어야겠습니다. 피곤에 너무 찌들어서 한참을 골골거렸다는 ㅋㅋ 그럼 다들 좋은 밤 되세요. ;)


ps) 다음은 MINT64 OS에서 전송한 ASCII Art 파일을 표시한 것을 캡쳐한 화면입니다. 예전에 쓰던 마스코트인 까마귀입니다. 어때요? 비슷하죠? ㅎㅎ


이번 포스팅은 거의 2주 만에 하는 것 같군요. ;) 이번에는 파일 시스템을 구현하다 보니 양이 많아서 이제야 겨우 끝났습니다. 일단 인증샷부터 보시죠. ;)

<MINT 파일 시스템을 구동한 동영상>

MINT 파일 시스템은 FAT 파일 시스템처럼 클러스터를 링크로 연결하는 형태로 되어 있습니다. 사실 FAT 파일 시스템을 쓸까도 고민했었는데, FAT 파일 시스템을 정리하고 구현하려면 양이 많아질 것 같고, 그렇다고 정리를 안 할 수는 없으니 그냥 간단한 파일 시스템을 만드는 것으로 했습니다. 그래서 나온 것이 MINT 파일 시스템인데 아래와 같은 구조로 만들었습니다.

 

<MINT 파일 시스템의 전체적인 구조>

척 봐도 FAT 파일 시스템과 아주 유사하다는 것을 알 수 있습니다. 디렉터리 엔트리 구조도 아주 단순합니다. 디렉터리 엔트리는 32 byte이며 파일 이름 24 byte와 파일 크기 4 byte, 그리고 파일 시작 클러스터 4 byte가 전부입니다. 클러스터 크기가 4Kbyte이므로 한 클러스터에 최대 128개의 파일을 생성할 수 있습니다.

<디렉터리 엔트리(Directory Entry)의 형식과 루트 디렉터리(Root Directory)의 구조>

이쯤되면 FAT 파일 시스템을 구현하는 게 더 낫지 않냐고 생각할지도 모르겠지만... MINT 파일 시스템은 극단(?)의 제약 사항을 걸어서 구현할 코드의 량을 대폭 줄였습니다. 그 제약 사항이 뭐야 하면...

디렉터리는 클러스터 하나만 사용할 수 있다
디렉터리는 루트 디렉터리만 존재한다

그렇습니다~!!! 서브 디렉터리를 제공하지 않고, 루트 디렉터리의 크기를 고정함으로써 경로(Path)처리나 디렉터리 처리에 관련된 코드를 대폭 줄인 것입니다. 실제로 예전에 FAT 파일 시스템을 구현했을 때와 비교한다면, 1/3 수준입니다. 물론 아쉬운 부분이 있긴 하지만... MINT64 OS처럼 간단한 OS에서 쓰기에는 충분한 것 같습니다. 어렵게 구현하는 것 보다 일단 구현하기 편하고 잘 돌면 되지요. ;)

구현할 양이 작아진 덕분에 C 언어 표준 입출력 함수, 즉 fopen(), fread(), fwrite(), fclose(), fseek(), opendir(), readdir(), rewindir(), closedir() 함수도 구현할 수 있었습니다. 마치 윈도우나 리눅스에서 콘솔 프로그램을 작성하듯이 MINT64 OS에서도 가능하다는 이야기지요. ㅎㅎ 실제로 아래는 위의 동영상에서 파일을 쓰고 읽는데 사용된 코드입니다.



아아~ 이제 파일 시스템에 캐시(Cache)를 넣고 램 디스크를 추가해야겠군요. 원래 이번 주 월요일에 시작해야 했는데 파일 시스템을 만드는 것이 늦어져서 이제야 시작합니다. ㅠㅠ 아흑... 또 주말을 반납해야 한다는... ㅠㅠ 열심히 만들어서 곧 Milestone을 하나 올리겠습니다. ;)

그럼 다들 즐거운 주말 되세요. ;)

<QEMU에 등록된 20MB짜리 하드 디스크의 정보를 읽은 화면>


읏차~ 예상 외에 변수가 생겨서 생각보다 조금 더 걸렸군요. ㅠㅠ 예전에 짰던 코드에 또 버그가 나와서 고칠까 말까 고민하다 보니 시간이 꽤 지났습니다. ㅠㅠ 수정하는 게 당연한데 왜 고민한 건지 잘 모르겠네요. (잠결에 그랬나? ㅡ_ㅡa..)

<LBA 0 어드레스에 2 섹터를 쓴 화면>

일단 간단히 읽고 쓰고를 반복해 본 결과 별 문제가 없는 것 같으니, 파일 시스템으로 넘어가야겠습니다. 파일 시스템은 FAT 파일 시스템을 아주 가볍게 개량해서 만들 생각입니다. 글은 이렇게 썼지만 사실 이미 작년 이맘때쯤에 만들었습니다. ㅡ_ㅡa;;; 아주 허접하지만 FAT 파일 시스템 드라이버를 만드는 것보다 일도 작고(과연??) 나름대로 쓸 만해서 이걸로 가기로 했습니다. 뭐 이름은 MINT64 Simple File System으로 해서 MSFS....가 아니라 MINTFS로 해야겠군요. ㅡ_ㅡa... 어디서 많이 본 듯한 이름이... 쿨럭..;;;


아아~ 또 바쁘게 하나 해야겠습니다. ㅎㅎ 이번 주말에 파일 시스템 스크린샷을 올릴 수 있으면 좋을 텐데.... ^^;;; 일단 열심히~!!! 그럼 다들 좋은 밤 되세요 ;)


하드 디스크 디바이스 드라이버 관련 링크는 아래를 참고하세요

http://www.nondot.org/sabre/os/articles/DiskandDiscDrives/

이번에는 정말 아슬 아슬하게 기한을 맞췄군요. ㅠㅠ

시간이 너무 늦었으니 오늘은 그냥 화면만 올리고, 자세한 것은 내일 올리겠습니다. ;)

아래는 실행 화면입니다. ㅎㅎ 5개의 우선 순위를 설정할 수 있도록 수정 되었고, 그 외에 뭐 태스크 종료 기능과 우선 순위 변경 기능, 그리고 프로세서 사용률 측정 기능이 추가되었습니다. ;)

clip_image002

이크~ 이만 자야겠군요. 내일 또 회식이 있어서... ^^;;; 다들 좋은 밤 되세요. ;)

clip_image002[8]

에휴~ 이번 주부터 2주 동안은 MINT64 OS에 스케줄러를 구현할 예정입니다. 이번 주는 다음 주에 구현할 멀티 레벨 큐 스케줄러(Multi Level Queue Scheduler)를 위해 간단한 라운드 로빈 스케줄러를 넣고 있습니다. 좀 있으면 주말인데, 주말에 약속이 좀 있어서 과연 이번 주 안에 끝낼 수 있을지 모르겠군요. ^^;;;;

시간은 점점 흘러만 가고 진도는 잘 나가지 않는 가운데... 뭐 회사에 대한 고민들과 퇴사하는 후배의 모습이 겹쳐서 머리가 좀 뒤죽박죽입니다. ㅠㅠ 이거 원... 이런 불경기에 월급 안 깎이는 것만해도 고마워 해야 할 텐데 말입니다. ㅠㅠ 아무래도 배가 부른 것 같군요. 개구리 올챙이적 모른다고 병특 때 고생한 건 생각도 안 하는 듯... ㅠㅠ

에궁... 정신 똑바로 차려야겠습니다. 홧팅~!!! >ㅁ<)-b

ps) 위의 화면은 라운드 로빈 스케줄러를 구현해서 20개의 태스크를 생성한 화면입니다. 대부분의 OS가 그렇듯이 PIT Interrupt를 통해 태스크를 전환합니다. ^^;;; 원래 각 태스크가 화면 주변을 돌게 되어 있는데, 스크린 샷을 찍다보니 그냥 잡다한 글자만 보이는 군요. 약간 슬프다는(?)...

image 

헥헥... 이번 주와 지난 주에 좀 많이 놀았더니 진도 맞추기가 힘드네요. ^^;;;; 어쨌거나 겨우 맞췄습니다. 아슬아슬 했다랄까요 ^^;;;; 자칫 잘못했으면 오늘 밤도 거의 못 잘 뻔 했습니다. ㅠㅠ 크윽... 이게 뭐 하자는 짓인지... ㅠㅠ

이번 주는 멀티 태스킹에 관련된 기능을 정리했습니다. 멀티 태스킹의 핵심이라하면 당연히 컨텍스트(Context) 관리 기능이므로, 컨텍스트 처리에 대한 함수 위주로 작성했습니다. 결과는 위에서 보시는 것과 같이 대~성공~!!!! 두 개의 태스크가 전환하면서 서로 자기 차례라고 메시지를 우기고(?) 있는 모습입니다. ^^;;;; (사실 예전에 다 만들었던 코드를 붙여 넣은 것 밖에는 없어요 ㅠㅠ)

다음 주는 이것을 확장해서 스케줄러도 추가하고 태스크 생성 및 종료에 대한 API도 추가해서 나름 괜찮은 시분할 멀티 태스킹 기능을 추가할 예정입니다. 점점 회사 일에 압박이 들어오고 있어서 생각대로 잘 될지는 알 수 없지만, 그래도 열심히 하는 것 말고는 방법이 없군요. ^^;;;; 제 유일한 장점이 책상에 오래 앉아 있는 거니 이거라도 살려야지요 ㅎㅎ

아아~ 이제 다음 주를 위해 준비를 좀 해야겠습니다. 다들 그럼 좋은 밤 되세요 ;)

ps) 크윽... 귀신보다 무섭다는 일요일 밤이군요. ㅠㅠ 눈물납니다. 아주 그냥 ㅠㅠ


좀 있으면 할머니 댁에 가야함에도 불구하고 일정이 좀 밀린지라 미친듯이 작업했습니다(그것도 설날 새벽에 이 짓을..~!!! ㅠㅠ). 그 결과~!!! 일단 목표치까지는 완성했습니다. ;) 아우 이거 원 노가다가 아주 장난이 아니군요. 그리고 생각 난 김에 MileStone 성 글에는 앞에 [MileStone]을 달기로 했습니다.

예전에 한번 달았다가 별로 효용이 없어서 블로그를 옮기면서 안달았는데... 글을 검색하려니 태그로 검색하는 것 보다는 제목으로 검색하는게 더 눈에 들어오더라구요 ㅎㅎ 앞으로 어떻게 될지는 모르겟지만, 일단 다는 걸로 했습니다.

[MileStone]을 달려고 글을 찾던 도중... 64bit로 최초로 전환해서 올렸던 글을 봤습니다. 작년 7월이더군요. 허허... 그후 가능성을 검토하기 위해 한 3개월 투자해서 GUI까지 후딱 만들고 지금 2번째 만들고 있는 건데... 그간 고생이 참 많았던 것 같습니다. ㅠㅠ 수많은 가상 머신들을 테스트하며 무료로 쓸 수 있고 멀티 코어까지 지원하는 놈을 찾기가 쉽지 않더라구요. 개발 환경은 또 왜이렇게 구축하기가 힘든건지... 지금 생각하면 눈물이 앞을 가립니다. ㅠㅠ

어쨋거나 지금은 검증까지 완료된 상태니 다시 그런 고생은 안하겠지요. ;) 옛날 글을 보니 감회가 새로워서 한자 끄적거려 봅니다. ㅎㅎ

이크~ 더 늦기 전에 이만 자야겠군요. 다들 떡국 많이 드시고, 새해 복 많이 받으세요 ;)


프로젝트 홈페이지: http://dev.naver.com/projects/nanumfont/


작년부터 GUI에 사용할 무료 폰트가 없을까 많이 고민했었는데, 어제 웹서핑을 하다가 네이버에서 공개한 무료, 그것도 고정 폭 글꼴을 찾았습니다. @0@)-b 비트맵 방식으로 처리하는데 고정 폭만큼 편한 게 없는지라 테스트를 위해 바로 설치해 봤습니다.


아래의 그림은 제가 주로 쓰는 Bitstream Vera Mono 폰트와 나눔고딕 코딩 폰트를 비교한 것입니다. Bitstream에 비해 샤프한 느낌이 나고 한글이 예쁘게 잘 나온다는 것을 알 수 있습니다. 헷갈리기 쉬운 숫자 0과 영문 O를 쉽게 구분할 수 있도록 한 것도 맘에 드는군요. ;)



<나눔고딕 글꼴>



<Bitstream Vera Sans Mono>


Bitstream을 보다가 나눔 고딕을 보니 약간 어색한 문자가 보이기도 하지만, 공짜로 쓸 수 있고 한글이 예쁘게 잘 나오기 때문에 향후 나눔고딕 폰트를 본 따 GUI를 만들 생각입니다. MINT64 OS가 한층 더 이뻐지겠군요. ;) 프로젝트를 진행하시는 분께 감사의 메일이라도 보내야겠습니다.


아우~ 이제 좀 있으면 고향으로 출발해야 할 시간이군요. 다들 즐거운 설 되시고 떡국 많이 드세요 ;)

아아~  지난 주에 내내 정리하고 작업해서 인터럽트 처리에 기반이 되는 IDT와 TSS쪽 관련 작업을 완료했습니다. 아우~ 이번에는 생각보다 정리할 것이 많아서 아주 식겁했습니다. 분량이 다른 것보다 1.5배나 많아서 죽는 줄 알았거든요. ^^;;;;

이것 참... 역시 어림짐작으로 대충 가늠했더니만, 이런 일이 생기는군요. ㅡ_ㅡa... 이것 말고도 대충 대충 잡아 놓은 부분이 아주 많은데... 살짝 겁이 나기 시작했습니다. 올해 안에 끝낼 수나 있을지 모르겠네요. 이건 뭐... 미친 듯이 정리하지 않는 한 어렵겠다는 생각도 얼핏 들었습니다.

어쨋거나 시작한 일이니 마무리는 해야겠고... 도중에 그만두자니 성격에 안 맞고... 역시 전 고생을 사서하는 타입인 것 같습니다. ;) 죽이 되던 밥이 되던 달려 봐야겠습니다. ;)

이크... 벌써 또 이렇게 시간이 됐군요. 이만 자야겠습니다. 다들 좋은 밤 되세요

ps) 맨 앞의 그림은 Divide by zero 예외를 발생시켜서 임시 예외 핸들러를 부른 화면입니다. 아주 허접하지만 Milestome 용으로 올려 봅니다. ;)

오늘 블로그를 돌다가 Xeraph 님의 블로그에서 재미있는 글을 봤습니다. “인텔 기가비트 NIC의 성능 향상 기법”이라는 내용이었는데, 원문은 http://xeraph.egloos.com/4808876 에서 보실 수 있습니다.

내용을 간단히 요약하자면 기가 비트쯤 되면 초당 무시무시한 패킷이 오고 가는데, 이것을 패킷이 올 때마다 인터럽트를 발생하게 하여 처리하면 인터럽트 처리의 오버 헤드 때문에 시스템의 전체적인 효율이 떨어진다는 것입니다. 어차피 패킷은 주기적으로 들어온다고 가정하면 인터럽트가 아닌 타이머를 사용할 수 있고, 주기적으로 패킷을 한꺼번에 읽도록 하면 효율을 높일 수 있다는 내용입니다.

실제로도 인터럽트가 자주 발생하면 현재 수행 중인 컨텍스트를 저장하고 복원하는 오버 헤드 때문에, 시스템의 성능이 급격히 떨어지게 됩니다. 저도 그런 경험을 한번 했었는데, 이 글을 읽고 나니 번뜩 떠오르더군요. 예전에 2003년쯤 자작한 kkama OS를 구동시키기 위해 펜티엄 2 233Mhz를 가진 노트북을 샀었습니다. Dell사 꺼였는 데, 플로피 디스크를 내장하고 있었기 때문에 상당히 메리트가 있었지요. ㅎㅎ

OS를 만들면서 GUI도 갖다 붙이고, HDD도 갖다 붙이고 하다가 장난 삼아(?) 시리얼 포트 드라이버를 만들 때였습니다. 전송 속도를 115200으로 맞춰 놓고 PC에서 노트북으로 데이터를 전송했더니, 정상적으로 패킷이 수신되지 않는 문제가 발생했습니다. 이상하다 싶어서 전송하는 동안 아무런 작업을 하지 않았더니 제대로 수신되더군요.

몇 번을 반복한 결과 시리얼로 패킷이 전송되는 동안 OS가 비정상적으로 느려지고, 마우스와 키보드, 그리고 HDD의 인터럽트, 그리고 인터럽트 불가 지역을 동시 다발적으로 수행할 때 패킷이 빠진다는 것을 알았습니다. 순진하게 시리얼 포트의 인터럽트가 발생할 때 마다 패킷 하나씩만 읽어 가서 FIFO에 남은 패킷이 계속 인터럽트를 유발했던 것이지요. 그러다 보니 처리가 늦어지고  패킷은 FIFO에서 밀려 사라지고... 등등의 문제가 발생했었습니다.

해결 방안은 간단했습니다. 시리얼 포트의 FIFO 크기를 늘리고, 인터럽트가 발생했을 때 마다 FIFO에 있는 데이터를 모두 읽음으로써 인터럽트의 발생 회수를 줄인 것입니다. 더불어 인터럽트 불가 영역을 줄여서 인터럽트에 좀더 빨리 반응하도록 한 것도 도움이 됐습니다.

안 그래도 지금 OS를 새로 만들고 있는데, 이런 점을 고려해서 잘 만들어야겠다는 생각이 드는군요. 그 동안 잊고 있었는데, 이점을 고려하면서 해야 할 것 같습니다.

에궁... 그럼 이만 또 자야겠네요. ㅎㅎ 다들 좋은 밤 되세요 ;)

에궁... 테스트 버전의 키보드 드라이버를 MINT64 OS에 추가했습니다. ^^;;; 예전에 만든 OS는 필요한 키만 추려서 처리했는데, 이번에는 다 처리하도록 만들었습니다. 뭐 아직 정리가 좀 덜 되긴 했지만, 역시나 기록을 남긴다는 차원에서... ^^;;;

회사에서 맡은 일도 어느 정도 해결 한지라 부담 없이 작업에 몰두했더니, 밤이 꽤 깊었네요. 이만 자야겠습니다 . 자세한 포스팅은 내일 해야겠군요. ㅎㅎ 그럼 좋은 새벽(?) 되세요 ;)

안녕하세요, kkamagui 입니다. ;) 새해가 되어 처음으로 하는 포스팅이군요. 그간 일이 좀 있어서, 일도 좀 하고(휴가인데 말이죠... ㅠㅠ) 코드 정리 작업을 병행하다 보니 이제서야 하나 올립니다. ㅎㅎ 아우 휴가를 정신 없이 보냈네요. 그나마 위로 일찍 올라 왔으니 이 정도는 한 것 같습니다. 계속 밑에 있었다면 아마... GG ㅠㅠ

이제 월요일이 되면 다시 회사로 가야 하는 데... 끔찍하군요. 어디 짱 박혀서 하고 싶은 것만 하고 살 수는 없을까 심히 고려 중입니다. 나이라도 어리면 과감히 퇴사하고 다른 것에 뛰어들어 볼 텐데... 좀 있으면 꺾인 환갑이라 그럴 수도 없네요. ^^;;;; 그냥 회사 다니면서 잠 좀 줄여 이것 저것 하는 정도 밖에는.... 그나마 졸졸하던 칼퇴도 이번 달부터는 힘들듯... ㅠㅠ (아아~ 이거 난 언제 자라는 말이냐... ㅠㅠ)

위에 그림은 새로 정리해서 만든 MINT64 OS의 스크린 샷입니다. 점점 소스 공개가 불투명해지고 있는 상황에서 이런 스크린샷을 올리는 게 과연 옳은 일인지는 모르겠지만... 개발 기록을 남긴다는 차원에서 꾸준히 올리고 있습니다. 어찌됐던 빨리 마무리 되었으면 좋겠는데... 점점 알 수가 없네요. ㅠㅠ

앗... 벌써 시간이 이렇게... 일단 자야겠습니다. ^^;;; 다들 좋은 밤 되시고... 아 아니구나... 좋은 아침 되세요 ;)

회사에서 시간이 좀 남아서 정리를 하던 중에, 재미있는 글을 발견했습니다. 글 주제는 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 코드 정리하랴 정신이 없습니다. 정리하던 도중에 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... 이래서는 영 답이 안 나오는 데... 어떻게 해결 방법을 찾아야겠습니다. 반드시 말이죠. ㅠㅠ

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

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

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

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

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

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

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

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

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

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


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


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

+ Recent posts