이전에 만든 부트로더에 추가하여, 특정 섹션을 메모리에 올리는 것을 시도함
[org 0x10000]
[bits 16]
mov ax, 0xB800
mov es, ax
mov byte[es:4], 'i'
mov byte[es:5], 0x09
mov byte[es:6], 'h'
mov byte[es:7], 0x09
jmp $
times 512-($-$$) db
[org 0]
[bits 16]
jmp 0x07C0:start
start:
mov ax, 0xB800
mov es, ax
mov byte[es:0], 'h'
mov byte[es:1], 0x09
mov byte[es:2], 'i'
mov byte[es:3], 0x09
jmp 0x1000:0
times 510-($-$$) db 0
dw 0xAA55
이렇게 작성하고
nasm -f bin -o boot.img boot.asm
nasm -f bin -o sector.img sector.asm
컴파일해주고
cat boot.img sector.img > out.img
합쳐주면 out.img가 생긴다.
하지만 작동하지 않았다.
[org 0]
[bits 16]
jmp 0x07C0:start
start:
mov ax, 0xB800
mov es, ax
mov byte[es:0], 'h
mov byte[es:1], 0x09
mov byte[es:2], 'i'
mov byte[es:3], 0x09
read:
mov ax, 0x1000
mov es, ax
mov bx, 0 ; 0x1000:0000 주소로 읽어 => 물리주소 0x10000
mov ah, 2 ; 디스크에 있는 데이터를 es:bx의 주소로
mov al, 1 ; 1섹터를 읽을 것이다
mov ch, 0 ; 0번째 실린더
mov cl, 2 ; 2번째 섹터부터 읽기 시작한다
mov dh, 0 ; 헤드는 0
mov dl, 0 ; 플로피 디스크 읽기
int 13h
jc read ; 에러나면 다시
jmp 0x1000:0
times 510-($-$$) db 0
dw 0xAA55
이렇게 수정하면 된다.
해결 : [디스크 -> 메모리] 로드하는 부분을 작성해야한다.
[org 0x11000]
[bits 16]
mov ax, 0xB800
mov es, ax
mov byte[es:4], 'i'
mov byte[es:5], 0x09
mov byte[es:6], 'h'
mov byte[es:7], 0x09
jmp $
times 512-($-$$) db
[org 0]
[bits 16]
jmp 0x07C0:start
start:
mov ax, 0xB800
mov es, ax
mov byte[es:0], 'h'
mov byte[es:1], 0x09
mov byte[es:2], 'i'
mov byte[es:3], 0x09
read:
mov ax, 0x1100
mov es, ax
mov bx, 0 ;
mov ah, 2 ; 디스크에 있는 데이터를 es:bx의 주소로
mov al, 1 ; 1섹터를 읽을 것이다
mov ch, 0 ; 0번째 실린더
mov cl, 2 ; 2번째 섹터부터 읽기 시작한다
mov dh, 0 ; 헤드는 0
mov dl, 0 ; 플로피 디스크 읽기
int 13h
jc read ; 에러나면 다시
jmp 0x1100:0
times 510-($-$$) db 0
dw 0xAA55
이 코드도 작동한다.
여기서 한참을 삽질했는데, 위 코드의 수정사항은 메모리 적재 위치를 0x11000으로 하도록 한 것이다.
16bit환경에서 주소 표기방식을 잘못 이해했기 때문에 한참을 헤매었다.
----삽질 기록----
메모리 할당이 의도한 대로 되지 않았음
cat 1.img 2.img > 3.img
이렇게 하면 제대로 된다.
그래도 해결이 안되는 부분이 있었다.
지피티가 살려줬다알려줬다
라고 한다.
-----------------------------끝------------------
삽질을 바탕으로 잘못된 이해를 바로잡았다...
; Boot.asm
[org 0]
[bits 16]
jmp 0x07C0:start
start:
mov ax, cs
mov ds, ax
mov es, ax
mov ax, 0xB800
mov es, ax
mov byte[es:0], 'h'
mov byte[es:1], 0x09
mov byte[es:2], 'i'
mov byte[es:3], 0x09
read:
mov ax, 0x1000
mov es, ax
mov bx, 0 ; 0x1000:0000 주소로 읽어 => 물리주소 0x10000
mov ah, 2 ; 디스크에 있는 데이터를 es:bx의 주소로
mov al, 1 ; 1섹터를 읽을 것이다
mov ch, 0 ; 0번째 실린더
mov cl, 2 ; 2번째 섹터부터 읽기 시작한다
mov dh, 0 ; 헤드는 0
mov dl, 0 ; 플로피 디스크 읽기
int 13h
jc read ; 에러나면 다시
mov dx, 0x3F2 ;플로피디스크 드라이브의
xor al, al ; 모터를 끈다
out dx, al
cli
lgdt[gdtr]
mov eax, cr0
or eax, 1
mov cr0, eax
jmp $+2
nop
nop
mov bx, DataSegment
mov ds, bx
mov es, bx
mov fs, bx
mov gs, bx
mov ss, bx
jmp dword CodeSegment:0x10000
gdtr:
dw gdt_end - gdt - 1
dd gdt+0x7C00
gdt:
dd 0,0 ; NULL 세그
CodeSegment equ 0x08
dd 0x0000FFFF, 0x00CF9A00 ; 코드 세그
DataSegment equ 0x10
dd 0x0000FFFF, 0x00CF9200 ; 데이터 세그
VideoSegment equ 0x18
dd 0x8000FFFF, 0x0040920B ; 비디오 세그
gdt_end:
times 510-($-$$) db 0
dw 0xAA55
; Sector2.asm
CodeSegment equ 0x08
DataSegment equ 0x10
VideoSegment equ 0x18
[org 0x10000]
[bits 32]
mov ax, VideoSegment
mov es, ax
mov byte[es:0x08], 'P'
mov byte[es:0x09], 0x09
jmp $
times 512-($-$$) db 0
Boot.asm에서 hi를 찍은 후 -> 하드디스크 읽기를 통해 섹터2를 0x10000에 적재 -> 16비트 환경을 32비트 환경으로 바꾸고 -> Sector2.asm(0x10000)으로 jmp 통해 이동 -> Sector2.asm에서 P 출력
하는 코드이다.
직접 작성한 코드가 아니라, 이해하는데 어려움이 있었다.
https://itguava.tistory.com/15?category=630867
[OS 개발 10] 32비트 커널 로더(4) - 커널 구현과 분석
1. 부트로더에서 커널 구현부로의 점프 앞서 언급한대로, 부트로더에서 커널 구현부로 넘어가는 부분을 우선 구현해야할 것입니다. 다음 코드를 보시죠. 위 코드는 부트로더를 확장하여 작성한
itguava.tistory.com
여기를 참고하면 이해가 쉽다.
결국 이 내용을 이해하면 끝이다.
prefix에 대해서는 나중에 따로 정리할 예정이다.
'study' 카테고리의 다른 글
[학점을 챙기자]구글 설문지 파이썬으로 정리하기 (0) | 2024.03.14 |
---|---|
SVN 사용법 (0) | 2024.03.05 |
[OS만들기]BOOTLOADER (0) | 2024.02.24 |
[WORKSTATION 구축]뻘짓진행 - NAS, DAS, SAN 정리 (0) | 2024.01.29 |
PGP 란, 이메일 암호화/복호화 (0) | 2024.01.28 |