Skip to content

Instantly share code, notes, and snippets.

@proob
Forked from MajsterTynek/bootsect.asm
Created October 15, 2018 18:56
Show Gist options
  • Select an option

  • Save proob/d7172d6774191e8404d6e6caf84f79c9 to your computer and use it in GitHub Desktop.

Select an option

Save proob/d7172d6774191e8404d6e6caf84f79c9 to your computer and use it in GitHub Desktop.

Revisions

  1. @MajsterTynek MajsterTynek created this gist Feb 21, 2017.
    34 changes: 34 additions & 0 deletions bootsect.asm
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,34 @@
    [bits 16]
    [org 0x7c00]
    ; BIOS loads it at ... or ... :
    ; CS:IP = 07c0:0000
    ; CS:IP = 0000:7c00
    jmp word 0x0000:start
    start: ; just to be sure it has proper origin

    ; loading machine code from floppy
    mov ah, 2 ; int 13h service: read sectors
    mov al, sectors ; number of sectors to load
    mov ch, 0 ; low eight bits of cylinder number
    mov cl, 2 ; sectors start from 1, or so they say ;)
    mov dh, 0 ; head number
    ; mov dl, ? ; drive number ; set by BIOS

    ; preparing data buffer at 0x2000:0x0000
    mov bx, 0x2000
    mov es, bx
    xor bx, bx ; bx := 0

    int 13h ; run service

    ; jump to loaded code
    jmp word 0x2000:0x0000
    ; The CPU doesn't reach here. Ever. Hopefully.

    epilogue:
    %if ($ - $$) > 510
    %fatal "Bootloader code exceed 512 bytes."
    %endif

    times 510 - ($ - $$) db 0 ; padding
    db 0x55, 0xAA ; magic number ;)
    44 changes: 44 additions & 0 deletions build.bat
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,44 @@

    @rem epilogue
    @ECHO OFF
    setlocal
    call :main argc argv envp
    goto :EOF

    rem Thanks to Gynvael Coldwind. // M.S. ;P
    rem "goto :EOF" inside called func/label means return

    rem This batch script is under "Spaghetti license":
    rem "Feel free to use any part of this code
    rem for your own projects. Enjoy your spaghetti! ".

    :sizeoffile
    set lastsize=%~z1
    goto :EOF

    :build_failed
    echo.Build failed.
    goto :EOF

    :too_many_sectors
    echo.In Bootsect: int 13h (service: 2):
    echo. can't read this amount of sectors: %sectors%
    goto build_failed
    goto :EOF

    :main
    nasm code.asm
    if errorlevel 1 goto build_failed

    call :sizeoffile code
    set /A sectors=(lastsize+511)/512
    if %sectors% gtr 255 goto too_many_sectors

    nasm bootsect.asm -dsectors=%sectors%
    if errorlevel 1 goto build_failed

    copy /B bootsect+code floppy.img 1>NUL
    if errorlevel 1 goto build_failed

    echo.Build succed.
    goto :EOF
    53 changes: 53 additions & 0 deletions code.asm
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,53 @@
    [bits 16]
    [org 0x0000]

    mov ax, 0x2000
    mov ds, ax
    mov es, ax

    mov ax, 0x1f00
    mov ss, ax
    xor sp, sp

    cli ; disable interrupts
    lgdt [GDT_address] ; load GDT adrress
    mov eax, cr0
    or al, 1 ; set PE bit in CR0
    mov cr0, eax

    ; Perform far jump to selector 08h
    ; (to load CS with proper PM32 descriptor)
    jmp dword 0x8:(0x20000+ProtectedModeMain)

    ProtectedModeMain:
    [bits 32]
    mov ax, 0x10
    mov ds, ax
    mov es, ax
    mov ss, ax

    lea eax, [0xb8000] ; 0xb0000 for monochromatic monitor
    mov dword [eax], 0x47694748 ; "Hi" white text on red background

    halt:
    hlt ; stays here forever
    jmp halt

    GDT_address:
    dw (GDT_end - GDT_begin) - 1
    dd 0x20000 + GDT_begin

    times (32 - ($ - $$) % 32) db 0xcc

    GDT_begin: ; GLOBAL DESCRIPTOR TABLE 32-BIT
    ; Null segment
    dd 0, 0
    ; Code segment
    dd 0xffff ; segment limit
    dd (10 << 8) | (1 << 12) | (1 << 15) | (0xf << 16) | (1 << 22) | (1 << 23)
    ; Data segment
    dd 0xffff ; segment limit
    dd (2 << 8) | (1 << 12) | (1 << 15) | (0xf << 16) | (1 << 22) | (1 << 23)
    ; Null segment
    dd 0, 0
    GDT_end:
    2 changes: 2 additions & 0 deletions opencmd.bat
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,2 @@
    @prompt ]$S
    @cmd /k