Reputation: 41
I know this is naive but I want my entire OS code written in assembly and that includes the IDT, but I don't recall there having ever been an IDT in assembly so I used objconv
but it outputs some code that I think is for EXEs instead of binart/OS and I have been debugging this code. I cannot figure why it errors because of the 'special symbols' that are in isg
, ieg
, idg
, imake
, and I can't use BOCHS because I can't assemble the code.
The IDT code written in C can be found in Nanobytes tutorial and the full outputted ASM code is below.
The code:
bootloader
:
[org 0x7C00]
[bits 16]
%define ENDL 0x0D, 0x0A
jmp short start
nop
bdb_oem: db 'CHOMPER.'
bdb_bytes_per_sector: dw 512
bdb_sectors_per_cluster: db 1
bdb_reserved_sectors: dw 1
bdb_fat_count: db 2
bdb_dir_entries_count: dw 0E0h
bdb_total_sectors: dw 2880
bdb_media_descriptor_type: db 0F0h
bdb_sectors_per_fat: dw 9
bdb_sectors_per_track: dw 18
bdb_heads: dw 2
bdb_hidden_sectors: dd 0
bdb_large_sector_count: dd 0
ebr_drive_number: db 0
db 0
ebr_signature: db 29h
ebr_volume_id: db 12h, 34h, 56h, 78h
ebr_volume_label: db 'CHOMPER. OS'
ebr_system_id: db 'FAT12 '
start:
xor ax, ax
mov ds, ax
mov es, ax
mov ss, ax
mov sp, 0x7C00
push es
push word .after
retf
.after:
mov [ebr_drive_number], dl
mov si, msg_loading
call puts
push es
mov ah, 08h
int 13h
jc floppy_error
pop es
and cl, 0x3F
xor ch, ch
mov [bdb_sectors_per_track], cx
inc dh
mov [bdb_heads], dh
mov ax, [bdb_sectors_per_fat]
mov bl, [bdb_fat_count]
xor bh, bh
mul bx
add ax, [bdb_reserved_sectors]
push ax
mov ax, [bdb_dir_entries_count]
shl ax, 5
xor dx, dx
div word [bdb_bytes_per_sector]
test dx, dx
jz .root_dir_after
inc ax
.root_dir_after:
mov cl, al
pop ax
mov dl, [ebr_drive_number]
mov bx, buffer
call disk_read
xor bx, bx
mov di, buffer
.search_kernal:
mov si, file_kernal_bin
mov cx, 11
push di
repe cmpsb
pop di
je .found_kernal
add di, 32
inc bx
cmp bx, [bdb_dir_entries_count]
jl .search_kernal
jmp kernal_not_found_error
.found_kernal:
mov ax, [di + 26]
mov [kernal_cluster], ax
mov ax, [bdb_reserved_sectors]
mov bx, buffer
mov cl, [bdb_sectors_per_fat]
mov dl, [ebr_drive_number]
call disk_read
mov bx, kernal_LOAD_SEGMENT
mov es, bx
mov bx, kernal_LOAD_OFFSET
.load_kernal_loop:
mov ax, [kernal_cluster]
add ax, 31
mov cl, 1
mov dl, [ebr_drive_number]
call disk_read
add bx, [bdb_bytes_per_sector]
mov ax, [kernal_cluster]
mov cx, 3
mul cx
mov cx, 2
div cx
mov si, buffer
add si, ax
mov ax, [ds:si]
or dx, dx
jz .even
.odd:
shr ax, 4
jmp .next_cluster_after
.even:
and ax, 0x0FFF
.next_cluster_after:
cmp ax, 0x0FF8
jae .read_finish
mov [kernal_cluster], ax
jmp .load_kernal_loop
.read_finish:
mov dl, [ebr_drive_number]
mov ax, kernal_LOAD_SEGMENT
mov ds, ax
mov es, ax
jmp kernal_LOAD_SEGMENT:kernal_LOAD_OFFSET
jmp wait_key_and_reboot
cli
hlt
floppy_error:
mov si, msg_read_failed
call puts
jmp wait_key_and_reboot
kernal_not_found_error:
mov si, msg_kernal_not_found
call puts
jmp wait_key_and_reboot
wait_key_and_reboot:
xor ah, ah
int 16h
jmp 0FFFFh:0
.halt:
cli
hlt
puts:
push si
push ax
push bx
.loop:
lodsb
or al, al
jz .done
mov ah, 0x0E
xor bh, bh
int 0x10
jmp .loop
.done:
pop bx
pop ax
pop si
ret
lba_to_chs:
push ax
push dx
xor dx, dx
div word [bdb_sectors_per_track]
inc dx
mov cx, dx
xor dx, dx
div word [bdb_heads]
mov dh, dl
mov ch, al
shl ah, 6
or cl, ah
pop ax
mov dl, al
pop ax
ret
disk_read:
push ax
push bx
push cx
push dx
push di
push cx
call lba_to_chs
pop ax
mov ah, 02h
mov di, 3
.retry:
pusha
stc
int 13h
jnc .done
popa
call disk_reset
dec di
test di, di
jnz .retry
.fail:
jmp floppy_error
.done:
popa
pop di
pop dx
pop cx
pop bx
pop ax
ret
disk_reset:
pusha
xor ah, ah
stc
int 13h
jc floppy_error
popa
ret
msg_loading: db 'BOOT START', ENDL, 0
msg_read_failed: db 'FAIL READ DISK', ENDL, 0
msg_kernal_not_found: db 'KERNAL NOT FOUND', ENDL, 0
file_kernal_bin: db 'KERNAL BIN'
kernal_cluster: dw 0
kernal_LOAD_SEGMENT equ 0x0000
kernal_LOAD_OFFSET equ 0x8000
times 510-($-$$) db 0
dw 0AA55h
`buffer`:
kernal
(ignore drawing code as it was from a MASM project and I just put some 32-bit things inside it for 'testing'):
[org 0x8000]
[bits 16]
jmp short start
gdt_start:
dq 0x0000000000000000
dq 0x00CF9A000000FFFF
dq 0x00CF92000000FFFF
dq 0x00CF92000000FFFF
gdt_end:
gdt_descriptor:
dw gdt_end - gdt_start - 1
dd gdt_start
print:
push si
push ax
push bx
.loop:
lodsb
or al, al
jz .done
mov ah, 0x0E
mov bh, 0
int 0x10
jmp .loop
.done:
pop bx
pop ax
pop si
ret
start:
mov si, start_sixteen
call print
in al, 0x64
.wait_ibe:
test al, 0x02
jnz .wait_ibe
mov al, 0xD1
out 0x64, al
.wait_ibe2:
in al, 0x64
test al, 0x02
jnz .wait_ibe2
mov al, 0xDF
out 0x60, al
first_sixteen:
cli
lgdt [gdt_descriptor]
mov eax, cr0
or eax, 1
mov cr0, eax
jmp dword 0x08:.afterstart
[bits 32]
.afterstart:
mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
global isg: function
global ieg: function
global idg: function
global imake: function
global IDTDescriptor
extern IDTLoad
extern IDT
jmp short isg
global i686IDTLoad
i686IDTLoad:
push ebp
mov ebp, esp
mov eax, [ebp + 8]
lidt [eax]
mov esp, ebp
pop ebp
ret
section .idt align=4
isg:
push ebp
mov ebp, esp
sub esp, 8
mov edx, dword [ebp+10H]
mov eax, dword [ebp+14H]
mov word [ebp-4H], dx
mov byte [ebp-8H], al
mov eax, dword [ebp+0CH]
mov edx, eax
mov eax, dword [ebp+8H]
mov word [IDT+eax*8], dx
mov eax, dword [ebp+8H]
movzx edx, word [ebp-4H]
mov word [IDT+2H+eax*8], dx
mov eax, dword [ebp+8H]
mov byte [IDT+4H+eax*8], 0
mov eax, dword [ebp+8H]
movzx edx, byte [ebp-8H]
mov byte [IDT+5H+eax*8], dl
mov eax, dword [ebp+0CH]
shr eax, 16
mov edx, eax
mov eax, dword [ebp+8H]
mov word [IDT+6H+eax*8], dx
nop
leave
ret
ieg:
push ebp
mov ebp, esp
mov eax, dword [ebp+8H]
movzx eax, byte [IDT+5H+eax*8]
or eax, 0FFFFFF80H
mov edx, eax
mov eax, dword [ebp+8H]
mov byte [IDT+5H+eax*8], dl
nop
pop ebp
ret
idg:
push ebp
mov ebp, esp
mov eax, dword [ebp+8H]
movzx eax, byte [IDT+5H+eax*8]
and eax, 7FH
mov edx, eax
mov eax, dword [ebp+8H]
mov byte [IDT+5H+eax*8], dl
nop
pop ebp
ret
imake:
push ebp
mov ebp, esp
sub esp, 24
mov dword [esp], IDTDescriptor
call i686IDTLoad
nop
leave
ret
nop
nop
IDTDescriptor:
db 0FFH, 07H, 00H, 00H
dd IDT
SECTION .drectve align=4
db 20H, 2DH, 61H, 6CH, 69H, 67H, 6EH, 63H
db 6FH, 6DH, 6DH, 3AH, 22H, 5FH, 67H, 5FH
db 49H, 44H, 54H, 22H, 2CH, 35H, 00H, 00H
SECTION .rdata$zzz align=4
db 47H, 43H, 43H, 3AH, 20H, 28H, 4DH, 69H
db 6EH, 47H, 57H, 2EH, 6FH, 72H, 67H, 20H
db 47H, 43H, 43H, 2DH, 36H, 2EH, 33H, 2EH
db 30H, 2DH, 31H, 29H, 20H, 36H, 2EH, 33H
db 2EH, 30H, 00H, 00H
cli
hlt
start_prog:
mov al, 2
mov ax, 1004
mov [Xval], eax
mov ax, 700
mov [Yval], eax
mov ax, 10
mov [Wval], eax
mov ax, 20
mov [Hval], eax
lea si, [PySpr]
call draw_spr
.halt:
cli
hlt
draw_spr:
xor edx, edx
mov ecx, [Hval]
draw_sprite:
mov eax, [Yval]
mov ebx, 1024
mul ebx
add eax, [Xval]
add edi, eax
push ecx
mov ecx, [Wval]
draw_pixels:
mov al, [si]
cmp al, 5
je skip_pixel_2
cld
movsb
jmp skip_pixel
skip_pixel_2:
inc edi
skip_pixel:
inc si
loop draw_pixels
pop ecx
mov eax, [Yval]
inc eax
mov [Yval], eax
loop draw_sprite
ret
start_sixteen: db 'KERNAL START', 0x0D, 0x0A, 0
Xval dd 0
Yval dd 0
Wval dd 0
Hval dw 0
PySpr db 5,5,5,2,2,2,2,5,5,5
db 5,5,2,2,2,2,2,2,5,5
db 5,2,2,2,2,2,2,2,2,5
db 2,2,2,2,2,2,2,2,2,2
db 5,8,8,8,8,8,8,8,8,5
db 5,8,15,0,8,8,0,15,8,5
db 5,8,8,8,8,8,8,8,8,5
db 5,8,8,0,0,0,0,8,8,5
db 5,5,8,8,8,8,8,8,5,5
db 2,2,2,2,2,2,2,2,2,2
db 2,2,2,2,2,2,2,2,2,2
db 2,5,2,2,2,2,2,2,5,2
db 2,5,2,2,2,2,2,2,5,2
db 2,5,2,2,2,2,2,2,5,2
db 8,5,2,2,2,2,2,2,5,8
db 5,5,6,6,6,6,6,6,5,5
db 5,5,6,6,5,5,6,6,5,5
db 5,5,6,6,5,5,6,6,5,5
db 5,5,6,6,5,5,6,6,5,5
db 5,7,7,7,5,5,7,7,7,5
Assembly output of idt.o
:
; Disassembly of file: idt.o
; Sat Dec 28 09:27:06 2024
; Type: COFF32
; Syntax: NASM
; Instruction set: 80386
global _i686_isg: function
global _i686_IDT_EnableGate: function
global _i686_IDT_DisableGate: function
global _i686_IDT_Initialize: function
global IDTDescriptor
extern _i686_IDT_Load ; near
extern IDT ; word
SECTION .text align=4 exec ; section number 1, code
.text: ; Local function
_i686_isg:
push ebp ; 0000 _ 55
mov ebp, esp ; 0001 _ 89. E5
sub esp, 8 ; 0003 _ 83. EC, 08
mov edx, dword [ebp+10H] ; 0006 _ 8B. 55, 10
mov eax, dword [ebp+14H] ; 0009 _ 8B. 45, 14
mov word [ebp-4H], dx ; 000C _ 66: 89. 55, FC
mov byte [ebp-8H], al ; 0010 _ 88. 45, F8
mov eax, dword [ebp+0CH] ; 0013 _ 8B. 45, 0C
mov edx, eax ; 0016 _ 89. C2
mov eax, dword [ebp+8H] ; 0018 _ 8B. 45, 08
mov word [IDT+eax*8], dx ; 001B _ 66: 89. 14 C5, 00000000(d)
mov eax, dword [ebp+8H] ; 0023 _ 8B. 45, 08
movzx edx, word [ebp-4H] ; 0026 _ 0F B7. 55, FC
mov word [IDT+2H+eax*8], dx ; 002A _ 66: 89. 14 C5, 00000002(d)
mov eax, dword [ebp+8H] ; 0032 _ 8B. 45, 08
mov byte [IDT+4H+eax*8], 0 ; 0035 _ C6. 04 C5, 00000004(d), 00
mov eax, dword [ebp+8H] ; 003D _ 8B. 45, 08
movzx edx, byte [ebp-8H] ; 0040 _ 0F B6. 55, F8
mov byte [IDT+5H+eax*8], dl ; 0044 _ 88. 14 C5, 00000005(d)
mov eax, dword [ebp+0CH] ; 004B _ 8B. 45, 0C
shr eax, 16 ; 004E _ C1. E8, 10
mov edx, eax ; 0051 _ 89. C2
mov eax, dword [ebp+8H] ; 0053 _ 8B. 45, 08
mov word [IDT+6H+eax*8], dx ; 0056 _ 66: 89. 14 C5, 00000006(d)
nop ; 005E _ 90
leave ; 005F _ C9
ret ; 0060 _ C3
_i686_IDT_EnableGate:; Function begin
push ebp ; 0061 _ 55
mov ebp, esp ; 0062 _ 89. E5
mov eax, dword [ebp+8H] ; 0064 _ 8B. 45, 08
movzx eax, byte [IDT+5H+eax*8] ; 0067 _ 0F B6. 04 C5, 00000005(d)
or eax, 0FFFFFF80H ; 006F _ 83. C8, 80
mov edx, eax ; 0072 _ 89. C2
mov eax, dword [ebp+8H] ; 0074 _ 8B. 45, 08
mov byte [IDT+5H+eax*8], dl ; 0077 _ 88. 14 C5, 00000005(d)
nop ; 007E _ 90
pop ebp ; 007F _ 5D
ret ; 0080 _ C3
; _i686_IDT_EnableGate End of function
_i686_IDT_DisableGate:; Function begin
push ebp ; 0081 _ 55
mov ebp, esp ; 0082 _ 89. E5
mov eax, dword [ebp+8H] ; 0084 _ 8B. 45, 08
movzx eax, byte [IDT+5H+eax*8] ; 0087 _ 0F B6. 04 C5, 00000005(d)
and eax, 7FH ; 008F _ 83. E0, 7F
mov edx, eax ; 0092 _ 89. C2
mov eax, dword [ebp+8H] ; 0094 _ 8B. 45, 08
mov byte [IDT+5H+eax*8], dl ; 0097 _ 88. 14 C5, 00000005(d)
nop ; 009E _ 90
pop ebp ; 009F _ 5D
ret ; 00A0 _ C3
; _i686_IDT_DisableGate End of function
_i686_IDT_Initialize:; Function begin
push ebp ; 00A1 _ 55
mov ebp, esp ; 00A2 _ 89. E5
sub esp, 24 ; 00A4 _ 83. EC, 18
mov dword [esp], IDTDescriptor ; 00A7 _ C7. 04 24, 00000000(d)
call _i686_IDT_Load ; 00AE _ E8, 00000000(rel)
nop ; 00B3 _ 90
leave ; 00B4 _ C9
ret ; 00B5 _ C3
; _i686_IDT_Initialize End of function
nop ; 00B6 _ 90
nop ; 00B7 _ 90
SECTION .data align=4 noexec ; section number 2, data
IDTDescriptor: ; byte
db 0FFH, 07H, 00H, 00H ; 0000 _ ....
dd IDT ; 0004 _ 00000000 (d)
SECTION .bss align=4 noexec ; section number 3, bss
SECTION .drectve align=4 noexec ; section number 4, data
db 20H, 2DH, 61H, 6CH, 69H, 67H, 6EH, 63H ; 0000 _ -alignc
db 6FH, 6DH, 6DH, 3AH, 22H, 5FH, 67H, 5FH ; 0008 _ omm:"
db 49H, 44H, 54H, 22H, 2CH, 35H, 00H, 00H ; 0010 _ IDT",5..
SECTION .rdata$zzz align=4 noexec ; section number 5, const
db 47H, 43H, 43H, 3AH, 20H, 28H, 4DH, 69H ; 0000 _ GCC: (Mi
db 6EH, 47H, 57H, 2EH, 6FH, 72H, 67H, 20H ; 0008 _ nGW.org
db 47H, 43H, 43H, 2DH, 36H, 2EH, 33H, 2EH ; 0010 _ GCC-6.3.
db 30H, 2DH, 31H, 29H, 20H, 36H, 2EH, 33H ; 0018 _ 0-1) 6.3
db 2EH, 30H, 00H, 00H ; 0020 _ .0..
Build commands:
nasm scr/boot.asm -f bin -o build/boot.bin
nasm scr/kernal.asm -f bin -o build/kernal.bin
dd if=/dev/zero of=v_005.img bs=512 count=2880
mkfs.fat -F 12 -n NBOS v_005.img
dd if=boot.bin of=v_005.img conv=notrunc
mcopy -i v_005.img kernal.bin ::kernal.bin
Upvotes: 2
Views: 113