I create a small os (not finished) only with assembly 16 bit that works with qemu-system-i386.
But now i want to test it on a real machine and in case of errors make it compatible with a real PC.
This is the os
Makefile:
boot = bootloader.asm
kernel = kernel.asm
boot_o = bootloader.bin
kernel_o = kernel.bin
bin = myos.bin
asm_compiler = nasm
qemu = qemu-system-i386
compile:
$(asm_compiler) -f elf32 -g $(boot) -o $(boot_o)
$(asm_compiler) -f elf32 -g $(kernel) -o $(kernel_o)
ld -m elf_i386 -nmagic -T linker.ld -o $(bin) $(boot_o) $(kernel_o)
run:
$(qemu) -fda $(bin)
clean:
-rm $(boot_o)
-rm $(kernel_o)
-rm $(bin)
linker.ld:
OUTPUT_FORMAT(binary)
ENTRY(_start)
SECTIONS
{
. = 0x7c00;
bootloader :
{
bootloader.bin (.boot);
}
kernel :
{
kernel.bin (.kernel);
}
/DISCARD/ :
{
*(.bss*);
*(COMMON*);
}
}
bootloader.asm:
bits 16
section .boot
global _start
_start:
cli
xor ax, ax
mov ds, ax
mov es, ax
mov ss, ax
mov sp, 0x9000
mov bx, 0x7e00
mov al, 1
mov dh, 0
mov dl, 0
mov ch, 0
mov cl, 2
mov ah, 2
int 0x13
pusha
mov ax, 0x0700 ; function 07, AL=0 means scroll whole window
mov bh, 0x07 ; character attribute = white on black
mov cx, 0x0000 ; row = 0, col = 0
mov dx, 0x184f ; row = 24 (0x18), col = 79 (0x4f)
int 10h ; call BIOS video interrupt
popa
pusha
mov ah, 0x02
xor dx, dx
int 10h
mov si, boot_msg
mov ah, 0x0e
boot_characterLoop:
lodsb
or al, al
jz continue
int 10h
jmp boot_characterLoop
continue:
mov ah, 0x86
mov cx, 0xF
mov dx, 0x4240
int 15h
int 15h
int 15h
popa
jmp 0x7e00
boot_msg: db "The os is correctly loaded"
times 510-($-$$) db 0
dw 0xAA55
kernel.asm:
bits 16
section .kernel
global _start_kernel
_start_kernel:
mov ax, 0x3
int 10h
commandLoop:
mov si, user
call print
mov di, input_string
call input
ifCommand:
cld
mov si, C_shutdown
mov di, input_string
mov cx, CL_shutdown
repe cmpsb
jz thenCommandShutdown
cld
mov si, C_reboot
mov di, input_string
mov cx, CL_reboot
repe cmpsb
jz thenCommandReboot
cld
mov si, C_clear
mov di, input_string
mov cx, CL_clear
repe cmpsb
jz thenCommandClear
jmp elseCommand
thenCommandShutdown:
call shutdown
thenCommandReboot:
call reboot
thenCommandClear:
call clearScreen
jmp commandLoop
elseCommand:
mov si, input_string
call print
mov si, cmdNotFound
call print
call newLine
jmp commandLoop
exit:
cli
hlt
;- Includes --------------------+
%include "lib/console.asm" ; |
%include "lib/system.asm" ; |
;-------------------------------+
;- Variables ----------------------------------+
user: db "user >> ", 0 ; |
input_string: times 20 db 0 ; |
cmdNotFound: db ": command not found!", 0 ; |
;----------------------------------------------+
;- Commands Variables ------------------------------+
; |
C_shutdown: db "shutdown", 0 ; |
CL_shutdown equ $ - C_shutdown ; |
; |
C_reboot: db "reboot", 0 ; |
CL_reboot equ $ - C_reboot ; |
; |
C_clear: db "clear", 0 ; |
CL_clear equ $ - C_clear ; |
;---------------------------------------------------+
times 512-($-$$) db 0
How I can do? Do i need grub? (I use ubuntu 22.04.02 LTS)
ps. sorry for the grammar but I am italian and I am only 14😅
2
Answers
The easiest way would be to write your OS image to a USB thumb drive, and then boot the machine from that.
Plug in your thumb drive, then run
dmesg
to look at the kernel log and see the name of the new device. It will probably besdb
(SCSI Drive B).Double check that you’re writing to the right device, otherwise you’ll trash your installation!
Then:
You’ll need to make sure your target machine is configured:
Good luck!
With moving away from qemu and working on a ‘real machine’ come some changes that qemu probably took care of for you:
mov bh, 0
in the call to the SetCursorPosition function 02h.To grub or not to grub
I’m on a DOS/Windows system using BIOS firmware, so neither Ubuntu nor UEFI firmware.
Whenever I need to test a hobby OS, I put it on a 3.5" floppy disk that I can insert in an external floppy drive plugged into an USB port. The only thing I have to make sure is that the external device is highest in the boot order (so before the hard drive and/or optical drive). There’s a BIOS setup setting for that.
Instead of a floppy disk (easiest), I could just put it on an USB stick and have the BIOS pretend that the stick is a floppy disk.