; boot.asm
bits 16
start:
mov ax, 0x7c0
mov ds, ax
mov dx, 0x1f2
mov al, 10
out dx, al
mov dx, 0x1f3
mov al, 1
out dx, al
mov dx, 0x1f4
mov al, 0
out dx, al
mov dx, 0x1f5
mov al, 0
out dx, al
mov dx, 0x1f6
mov al, 0xe0
out dx, al
mov dx, 0x1f7
mov al, 0x20
out dx, al
mov dx, 0x1f7
.1:
in al, dx
and al, 0x88
cmp al, 0x8
jnz .1
mov dx, 0x1f0
mov cx, 10 * 256
mov bx, 0x200
.2:
in ax, dx
mov [bx], ax
inc bx
inc bx
loop .2
cli
lgdt [gdtr]
in al, 0x92
or al, 0x2
out 0x92, al
mov eax, cr0
or eax, 0x1
mov cr0, eax
jmp dword 1 * 8 : 0
gdt_start:
dq 0x0000_0000_0000_0000 ; 0 * 8
dq 0x00cf_9a00_7e00_ffff ; 1 * 8
dq 0x00cf_9200_7e00_ffff ; 2 * 8
dq 0x00c0_920b_8000_ffff ; 3 * 8
dq 0x00cf_9a00_0000_ffff ; 4 * 8
dq 0x00cf_9200_0000_ffff ; 5 * 8
gdt_end:
gdtr:
dw gdt_end - gdt_start - 1
dd gdt_start + 0x7c00
times 510 - ($ - $$) db 0
db 0x55, 0xaa
; loader.asm
bits 32
start:
mov ax, 3 * 8
mov gs, ax
mov ax, 2 * 8
mov ds, ax
mov ss, ax
mov esp, stack_top
xor ebx, ebx
mov byte [gs: ebx], 'P'
inc ebx
mov byte [gs: ebx], 0xc
inc ebx
mov dx, 0x1f2
mov al, 220
out dx, al
mov dx, 0x1f3
mov al, 11
out dx, al
mov dx, 0x1f4
mov al, 0
out dx, al
mov dx, 0x1f5
mov al, 0
out dx, al
mov dx, 0x1f6
mov al, 0xe0
out dx, al
mov dx, 0x1f7
mov al, 0x20
out dx, al
mov dx, 0x1f7
.1:
in al, dx
and al, 0x88
cmp al, 0x8
jnz .1
mov dx, 0x1f0
mov ecx, 220 * 256
mov ebx, 0x100000 - 0x7e00
.2:
in ax, dx
mov [ebx], ax
inc ebx
inc ebx
loop .2
sub esp, 20 * 4
mov dword [esp + 0 * 4], 0x7c00
mov dword [esp + 1 * 4], 0
mov dword [esp + 2 * 4], 0
mov dword [esp + 3 * 4], 0
mov dword [esp + 4 * 4], 0
call create_descriptor
mov dword [esp + 0 * 4], 0x7c00
mov dword [esp + 1 * 4], 1
mov dword [esp + 2 * 4], 0x100000
mov dword [esp + 3 * 4], 0x000fffff
mov dword [esp + 4 * 4], 0x9a + 0xc000
call create_descriptor
mov dword [esp + 0 * 4], 0x7c00
mov dword [esp + 1 * 4], 2
mov dword [esp + 2 * 4], 0x100000
mov dword [esp + 3 * 4], 0x000fffff
mov dword [esp + 4 * 4], 0x92 + 0xc000
call create_descriptor
mov dword [esp + 0 * 4], 0x7c00
mov dword [esp + 1 * 4], 3
mov dword [esp + 2 * 4], 0xb8000
mov dword [esp + 3 * 4], 0x00000fff
mov dword [esp + 4 * 4], 0x92 + 0xc000
call create_descriptor
mov dword [esp + 0 * 4], 0x7c00
mov dword [esp + 1 * 4], 4
mov dword [esp + 2 * 4], 0
mov dword [esp + 3 * 4], 0x000fffff
mov dword [esp + 4 * 4], 0x9a + 0xc000
call create_descriptor
mov dword [esp + 0 * 4], 0x7c00
mov dword [esp + 1 * 4], 5
mov dword [esp + 2 * 4], 0
mov dword [esp + 3 * 4], 0x000fffff
mov dword [esp + 4 * 4], 0x92 + 0xc000
call create_descriptor
lgdt [gdtr]
add esp, 20 * 4
jmp dword 1 * 8 : 0
%include "syslib.asm"
stack_bottom:
times 512 db 0
stack_top:
gdtr:
dw 256 * 8 - 1
dd 0x7c00
gdt_start:
dq 0x0000_0000_0000_0000 ; 0 * 8
dq 0x00cf_9a10_0000_ffff ; 1 * 8
dq 0x00cf_9210_0000_ffff ; 2 * 8
dq 0x00c0_920b_8000_ffff ; 3 * 8
dq 0x00cf_9a00_0000_ffff ; 4 * 8
dq 0x00cf_9200_0000_ffff ; 5 * 8
gdt_end:
gdtr1:
dw gdt_end - gdt_start - 1
dd gdt_start + 0x7e00
; kernel.asm
bits 32
start:
mov ax, 3 * 8
mov gs, ax
mov ax, 2 * 8
mov ds, ax
mov es, ax
mov fs, ax
mov ss, ax
mov esp, stack_top
call cls
mov ebx, 160 + 10
mov byte [gs: ebx], 'P'
inc ebx
mov byte [gs: ebx], 0xe
inc ebx
mov dword [esp + 0 * 4], 0x7c00
mov dword [esp + 1 * 4], 6
mov dword [esp + 2 * 4], 0x100000 + ldt_start
mov dword [esp + 3 * 4], ldt_end - ldt_start - 1
mov dword [esp + 4 * 4], 0x82
call create_descriptor
mov dword [esp + 0 * 4], 0x100000 + ldt_start
mov dword [esp + 1 * 4], 1
mov dword [esp + 2 * 4], 0x100000 + local_task_start
mov dword [esp + 3 * 4], local_task_end - local_task_start - 1
mov dword [esp + 4 * 4], 0x9a + 0xc000
call create_descriptor
mov dword [esp + 0 * 4], 0x100000 + ldt_start
mov dword [esp + 1 * 4], 0
mov dword [esp + 2 * 4], 0xb8000
mov dword [esp + 3 * 4], 0xfff
mov dword [esp + 4 * 4], 0x92 + 0xc000
call create_descriptor
mov dword [esp + 0 * 4], 0x7c00
mov dword [esp + 1 * 4], 7
mov dword [esp + 2 * 4], 0x100000 + call_gate_start
mov dword [esp + 3 * 4], call_gate_end - call_gate_start - 1
mov dword [esp + 4 * 4], 0x9a + 0xc000
call create_descriptor
mov dword [esp + 0 * 4], 0x7c00 ;
mov dword [esp + 1 * 4], 8 ;
mov dword [esp + 2 * 4], 7 * 8;
mov dword [esp + 3 * 4], 0x8c00 + 0x6000
mov dword [esp + 4 * 4], 0 ;
call create_gate
mov dword [esp + 0 * 4], 0x7c00
mov dword [esp + 1 * 4], 9
mov dword [esp + 2 * 4], 0x100000 + func1_start
mov dword [esp + 3 * 4], func1_end - func1_start - 1
mov dword [esp + 4 * 4], 0x9a + 0xc000 + 0x60
call create_descriptor
mov dword [esp + 0 * 4], 0x7c00
mov dword [esp + 1 * 4], 10
mov dword [esp + 2 * 4], 0x100000 + func1_stack_top
mov dword [esp + 3 * 4], func1_stack_bottom - func1_stack_top - 1
mov dword [esp + 4 * 4], 0x92 + 0xc000 + 0x60
call create_descriptor
mov dword [esp + 0 * 4], 0x7c00
mov dword [esp + 1 * 4], 11
mov dword [esp + 2 * 4], 0xb8000
mov dword [esp + 3 * 4], 0xfff
mov dword [esp + 4 * 4], 0x92 + 0xc000 + 0x60
call create_descriptor
mov dword [esp + 0 * 4], 0x7c00
mov dword [esp + 1 * 4], 12
mov dword [esp + 2 * 4], 0x100000 + tss_start
mov dword [esp + 3 * 4], tss_end - tss_start + 1
mov dword [esp + 4 * 4], 0x89
call create_descriptor
; call 8 * 8 : 0
; call 7 * 8 : 0
mov ax, 6 * 8
lldt ax
call 1 * 8 + 4 : 0
mov ebx, 640 + 10
mov byte [gs: ebx], 'p'
inc ebx
mov byte [gs: ebx], 0xf
inc ebx
mov ax, 12 * 8
ltr ax
push 10 * 8 + 3
push func1_stack_top
push 9 * 8 + 3
push 0
retf
.loop:
hlt
jmp .loop
%include "syslib.asm"
stack_bottom:
times 1024 db 0
stack_top:
cls: ; void cls(void)
enter
pusha
xor ebx, ebx
mov al, ' '
mov ah, 0xf
mov ecx, 2000
.1:
mov [gs: ebx], ax
inc ebx
inc ebx
loop .1
popa
leave
ret
align 4096
ldt_start:
dq 0, 0
ldt_end:
; align 4096
local_task_start:
mov ax, 0 * 8 + 4
mov gs, ax
mov ebx, 320 + 10
mov byte [gs: ebx], 'L'
inc ebx
mov byte [gs: ebx], 0x9
inc ebx
retf
local_task_end:
call_gate_start:
mov ax, 3 * 8
mov gs, ax
mov ebx, 960 + 10
mov byte [gs: ebx], 'c'
inc ebx
mov byte [gs: ebx], 0xf
inc ebx
retf
call_gate_end:
align 32
func1_stack_bottom:
times 128 db 0
func1_stack_top:
align 32
func1_start:
mov ax, 11 * 8 + 3
mov gs, ax
mov ebx, 800 + 10
mov byte [gs: ebx], '3'
inc ebx
mov byte [gs: ebx], 0xb
inc ebx
call 8 * 8 + 3: 0
jmp $
func1_end:
align 32
tss_start:
dd 0
dd stack_top
dd 2 * 8
times 26 - 3 - 1 dd 0
dw 0
dw tss_end
tss_end:
db 0xff
; sysmacro.asm
%macro enter 0
push ebp
mov ebp, esp
%endmacro
%macro push_some 0
push ecx
push edx
push ebx
push esi
push edi
%endmacro
%macro pop_some 0
pop edi
pop esi
pop ebx
pop edx
pop ecx
%endmacro
; syslib.asm
%include "sysmacro.asm"
; void create_descriptor(int table_start, int number, int base, int limit, int attrib)
; mov dword [esp + 0 * 4], 0x7c00
; mov dword [esp + 1 * 4], 1
; mov dword [esp + 2 * 4], 0x100000
; mov dword [esp + 3 * 4], 0x000fffff
; mov dword [esp + 4 * 4], 0x9a + 0xc000
; call create_descriptor
create_descriptor:
enter
pusha
push ds
mov ax, 5 * 8
mov ds, ax
mov word [ebx + 5], 0
mov ebx, [ebp + 2 * 4]
mov ecx, [ebp + 3 * 4]
shl ecx, 3
add ebx, ecx
mov eax, [ebp + 5 * 4]
mov [ebx], ax
shr eax, 16
and al, 0x0f
mov [ebx + 6], al
mov eax, [ebp + 4 * 4]
mov ecx, eax
and eax, 0x00ffffff
mov [ebx + 2], eax
shr ecx, 24
mov [ebx + 7], cl
mov ax, [ebp + 6 * 4]
or [ebx + 5], ax
pop ds
popa
leave
ret
; void create_gate(int table_start, int irq, int select, int attrib, int offset)
; mov dword [esp + 0 * 4], 0x7c00 + 256 * 8 ; interrupt descriptor table start
; mov dword [esp + 1 * 4], 0x20 ; clock interrupt
; mov dword [esp + 2 * 4], 4 * 8 ; code segment select
; mov dword [esp + 3 * 4], 0x8e00 ; interrupt gate
; mov dword [esp + 4 * 4], clock_int ; interrupt process program enter address
; call create_gate
create_gate:
enter
pusha
push ds
mov ax, 5 * 8
mov ds, ax
mov ebx, [ebp + 2 * 4]
mov ecx, [ebp + 3 * 4]
shl ecx, 3
add ebx, ecx
mov ax, [ebp + 4 * 4]
mov [ebx + 2], ax
mov ax, [ebp + 5 * 4]
mov [ebx + 4], ax
mov eax, [ebp + 6 * 4]
mov [ebx + 0], ax
shr eax, 16
mov [ebx + 6], ax
pop ds
popa
leave
ret
###############################################################
# bochsrc.txt file for DLX Linux disk image.
###############################################################
# how much memory the emulated machine will have
megs: 64
# filename of ROM images
romimage: file=../BIOS-bochs-latest
vgaromimage: file=../VGABIOS-lgpl-latest
# what disk images will be used
floppya: 1_44=a.img, status=inserted
##floppyb: 1_44=b.img, status=inserted
# hard disk
ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14
ata0-master: type=disk, path="c.img", cylinders=306, heads=4, spt=17
# choose the boot disk.
boot: c
# default config interface is textconfig.
#config_interface: textconfig
#config_interface: wx
#display_library: x
# other choices: win32 sdl wx carbon amigaos beos macintosh nogui rfb term svga
# where do we send log messages?
#log: bochsout.txt
# disable the mouse, since DLX is text only
mouse: enabled=0
# set up IPS value and clock sync
cpu: ips=15000000
clock: sync=both
# enable key mapping, using US layout as default.
#
# NOTE: In Bochs 1.4, keyboard mapping is only 100% implemented on X windows.
# However, the key mapping tables are used in the paste function, so
# in the DLX Linux example I'm enabling keyboard_mapping so that paste
# will work. Cut&Paste is currently implemented on win32 and X windows only.
keyboard: keymap=../keymaps/x11-pc-us.map
#keyboard: keymap=../keymaps/x11-pc-fr.map
#keyboard: keymap=../keymaps/x11-pc-de.map
#keyboard: keymap=../keymaps/x11-pc-es.map
rem auto.cmd
@echo off
nasm -fbin -o boot.bin boot.asm
dd if=boot.bin of=c.img seek=0 count=1
echo.
nasm -fbin -o loader.bin loader.asm
dd if=loader.bin of=c.img seek=1 count=10
echo.
nasm -fbin -o kernel.bin kernel.asm
dd if=kernel.bin of=c.img seek=11 count=220
echo.
rem del *.bin
del c.img.lock