부트로더 #1
부트로더를 만들어야 하는데, 어셈블리어 잘 모르는데 난감하다. 몇 번 훑어 본 걸로 만들 수 있을 지 모르겠다. 다른 부트로더를 참조해서 만들어야 겠다. 그래 (ㅠㅠ 나의 영혼이여~~ ) 근데, 부트로더는 어떻게 실행 할까? 라는 궁금증이 생겼다. 자 검색..검색..
음… 대충 컴퓨터가 전원이 켜질 경우 , 저장 매체의 첫 번째 섹터에서 512 바이트를 정해진 메모리에 로딩하고 해당 메모리를 프로그램으로 인식하고 실행한다. 라고 이해했다. 그러니까 첫 번째 섹터 512바이트를 읽어서 그걸 실행한다는 거군. 쉽네. 근데 왜 512바이트지?? 검색..검색.. 흠 못 찾겠다.
자 , 그러면 프로그래밍 한번 해보자!!! 아직, 부트로더 설계도 제대로 잡지 않았는데…음… 흠.
그냥 HELLO 한번 찍어 보자.
1: mov ax, 0 ; ax 레지스터를 0 으로 초기화 한다.
2: mov ds, ax ; ds 세그먼트 레지스터를 0으로 초기화 한다.
3: mov es, ax ; es 세그먼트 레지스터를 0으로 초기화 한다.
아직 여기밖에 모르겠다. 화면에 출력하려면 어떻게 하지?? 히유!! 답답하다…또 검색질 하자.
어셈블리어를 이용해서 화면에 글자를 출력하려면 BIOS 인터럽트 를 이용해야 한다고 하네.. 그래 인터럽트 한번 더 뒤져보자.
http://ko.wikipedia.org/wiki/%EB%B0%94%EC%9D%B4%EC%98%A4%EC%8A%A4_%EC%9D%B8%ED%84%B0%EB%9F%BD%ED%8A%B8_%ED%98%B8%EC%B6%9C 여기에 인터럽트 테이블 모아놓은 게 있네. INT 10h 이용하면 되겠다.
mov al, ‘a’
mov ah, 0x0E int 10h |
이걸 이용해서 다시 프로그래밍 한다.
cli ; 인터럽트 발생안되게 설정 xor ax,ax ; ax 0으로 초기화 한다. ax xor ax 어차피 0이다. mov ds, ax ; ds 세그먼트 레지스터를 0 으로 초기화 한다. mov es, ax ; es 세그먼트 레지스터를 0 으로 초기화 한다. sti ; 인터럽트 발생 설정 lea si, [HELLO_MSG] ; HELLO_MSG 위치 주소 call PRINT ; PRINT 함수 호출 PRINT: pusha ; 모든 레지스터를 스택에 넣는다. PRINT_LOOP: mov al, [si] ; al에 글자 하나 저장한다. inc si ; si 주소를 증가한다. or al, al ; or 연산. jz PRINT_END ; 문자열 끝이 or 연산이 0 이라면. 종료 mov ah,0x0E ; ah = 0xE int 0x10 ; 인터럽트 0x10h jmp PRINT_LOOP ; 다음 문자 출력 루프 PRINT_END: popa ;모든 레지스터 스택에서 뺀다. ret ;호출 한곳으로 리턴. HELLO_MSG: db "HELLO MY BOOTLOADER", 0x00 |
자 코드 입력은 했고 , 컴파일 해야지~~~^^
nasm –fbin –o BOOTLOADER BOOTLOADER.ASM
캬~~ 에러도 없다. BOOTLOADER 라는 파일이 생성 되었다.
자 이제 이걸 첫 번째 섹터에 복사해 주면 된다. 아~ 난 가상이미지 파일인데?? 어떻게 이걸 복사하지?? 아놔!!! ..흠…이미지 파일이니까 그냥 이미지 파일 찾아서 해당 첫 번째에다가 복사하면 되나?? 생각 난 김에 해보자!! 근데 이거 원… 가상 이미지 파일 있는 위치를 모르겠네 ㅡㅡ;;;
1. Windows Virtual PC 를 실행한다.
2. 생성한 가상 컴퓨터를 선택한다. 3. 설정 을 클릭한다. 4. 하드 디스크 1을 선택한다. 5. 가상 이미지 파일 위치를 찾았다! |
자 , vhd 확장자의 이미지 파일을 찾았다. ㅎㅎ 이제 에디터로 불러야지~~. 음… 울트라 에디터로 로딩할 까, Visual Studio 로 로딩 할까?? 아무래도 복사해야 하니 Visual Studio 에서 로딩 해야 할것 같다. 아악!! 128MB 다. 왜 이렇게 크게 만들었을까 ..ㅠㅠ 다시 만들까?? 귀찮다!!! 그냥 읽어 버렷!
깔끔하게 헥사뷰어 로 나온다. 울트라 에디트 보단 이게 좋지~^^ 아 부트로더 도 읽어야지~~Visual Studio에 부트로더 도 읽어 준다. 탭으로 왔다 갔다 하면 편하겠네..부트로더 헥사뷰어에서 코드를 이제 복사한다. 컴퓨터가 512바이트를 읽는다고 했으니, 512바이트를 복사하면 되겠다. 라인이 1f0까지 쭉 내려서 복사한다. 그리고 이미지 파일 헥사뷰어에서 똑같이 1f0 라인까지 선택 후, 붙이기 한다. 그리고 저장.!!!!
긴장된다. Windows Virtual PC 실행해서 가상 컴퓨터 작동해봐야지~~
한참을 기다려도 실행 안된다. 검은 화면…..이미지 파일 첫 부분에 파일 붙이기 하는게 안되는 건가?? 흠.. 인터넷에서 돌아다니는 부트로더로 컴파일 해서 복사, 붙이기 하니 화면이 뜬다. 이미지 파일 첫 부분에 붙이기 하는건 되는건가 보다. 내가 만든 코드는 아니지만 가상 컴퓨터 화면에 뭔가 출력은 되니, 쪼금 나도 희망이 생긴다. 음.. 뭐가 문제지?? 되는 부트로더 랑 비교해 보자!!
크게 다른 부분은 첫 부분하고 끝 부분이다.
times 510-($-$$) db 0x00
dw 0xAA55
이건 또 무슨 문법이야 ? 하고 검색해 보니, times 는 뭘 반복할 때 쓴다고 한다. $는 현재 위치를 나타내는 거고, $$줄 처음 위치를 나타내는 거란다. 그러면 저 명령어 들의 하는 짓은??? 그냥 510까지 0으로 채우는 짓이란다. 즉 내가 만든 코드는 50 바이트 밖에 안된다. 510-50 = 460 바이트를 0으로 다 채운다는 것이다. 어차피 0으로 다 채워져 있는데 뭘!! 흠.. 그리고 dw 0xAA55는 510 이후에 AA55라고 쓰기 위해서란다. 왜???? 컴퓨터가 512 바이트를 읽고 0xAA55 저놈이 있나 없나 체크 한단다!! 없으면 실행 안 해 준다네…
흠.. 그러니까 512 바이트 중 끝에 0xAA55가 있어야지 우선 실행해 준다는 거네. 그러면 코드에 times랑 0xAA55 넣고 컴파일….다시 가상 PC 작동…..오~~~~~~~~~~~~~~~~~ 뭔가 나온다!!!
아드래날린이 왕성하게 분비 되는지 흥분된다. 하하하 . 흠 근데 왜 글자가 안나오고 쓰레기값이 나오냐?? 코드 문제인가? 흠.. 동작하는 부트로더랑 비교해 봐야겠네…
첫부분에
org 0x7C00
bits 16
이 있다. 뭐 뒤에 쓰잘데기 없이 점프 명령어 있긴 한데 뭐 필요 없는 작업인것 같고… 요 두넘이 틀리다. 또 뭐하는 놈들이냐?? 검색..검색…(검색질도 지겹다 …)
ORG 0x7C00 : 컴퓨터가 내가 만든 부트로더를 0x7C00 메모리 위치에다가 로딩하는데, 내 부트로더는 데이터 변수 쓸때 그 데이터 변수 위치가 0으로 시작된 위치에 있으므로 찾지 못한다. 고로 첫줄에 똭!!!! 0x7C00 부터 시작 되게 하면 그 데이터를 쓸 수 있게 해준단다!
BITS 16 : 내가 작성하는게 16비트에서 작동하는 코드를 사용한다는 명령어란다. 흠!
뭐 이리 어렵나~~ 여튼 추가…
ORG 0x7C00 BITS 16 cli ; 인터럽트 발생안되게 설정 xor ax,ax ; ax 0으로 초기화 한다. ax xor ax 어차피 0이다. mov ds, ax ; ds 세그먼트 레지스터를 0 으로 초기화 한다. mov es, ax ; es 세그먼트 레지스터를 0 으로 초기화 한다. sti ; 인터럽트 발생 설정 lea si, [HELLO_MSG] ; HELLO_MSG 위치 주소 call PRINT ; PRINT 함수 호출 jmp $ PRINT: pusha ; 모든 레지스터를 스택에 넣는다. PRINT_LOOP: mov al, [si] ; al에 글자 하나 저장한다. inc si ; si 주소를 증가한다. or al, al ; or 연산. jz PRINT_END ; 문자열 끝이 or 연산이 0 이라면. 종료 mov ah,0x0E ; ah = 0xE int 0x10 ; 인터럽트 0x10h jmp PRINT_LOOP ; 다음 문자 출력 루프 PRINT_END: popa ;모든 레지스터 스택에서 뺀다. ret ;호출 한곳으로 리턴. HELLO_MSG: db "HELLO MY BOOTLOADER", 0x00 times 510-($-$$) db 0x00 dw 0xAA55 |
나 울뻔 했다…된다..
HELLO MY BOOTLOADER
화면에 출력된다. 검색 질 하느라 시간 보냈는데 출력이 되니 기쁘다. 이제 커널 파일 만들어서 부트로더에서 로딩시키고 커널 실행시키면 되겠다. 하하 이제 C 로 넘어간다. 알지도 못하는 어셈블리어로 벗어 난다니 더 기쁘다.
'프로그래밍 > OS 만들기' 카테고리의 다른 글
OS 만들기 #6 - MBR (0) | 2013.08.14 |
---|---|
OS 만들기 #5 - 부트로더 (0) | 2013.08.14 |
OS 만들기 #4 - 부트로더 (0) | 2013.08.14 |
OS 만들기 #2 (0) | 2013.08.14 |
OS 만들기 #1 (0) | 2013.08.14 |