os.asm (4428B)
1 [BITS 16] 2 [ORG 0x7c00] 3 4 db "#!/usr/bin/env sh", 0x0a 5 db ": <<'EOF'", 0x0a 6 ;;; Starting from here until EOF, all data is effectively ignored by Unix shells 7 ;;; End of line for MS-DOS, so that it correctly processes the comment 8 db 0x0d, 0x0a 9 10 ;;; The GOTO target must not be more than one block away (512 bytes by default 11 ;;; on some systems) apparently, so it is impractical since the target is 12 ;;; so far away in our case. Instead, we use a comment, but if there are some 13 ;;; compatibility issues with the comment syntax, we could likely still use 14 ;;; GOTO and insert intermediate jump points. 15 ;; db "GOTO msdos", 0x0d, 0x0a 16 db ":: " 17 18 ;;; The #!… above is interpreted as … jnz short 0x7c78 in x86 assembly. 19 times 0x7c78-0x7c00-($-$$) db 0 20 21 ;;; Switch to 320x200x256 VGA mode 22 mov ax, 0x0013 23 int 10h 24 25 ;;; Framebuffer address is 0xa000, store it into the fs register (the segment base, in multiples of 16) 26 push 0xa000 27 pop fs 28 29 ;;; Set pixel value (0, then increase at each step below) 30 xor bl, bl 31 32 ;;; set register di to 0 33 xor di,di 34 35 ;;; Store pixels, display something flashy. 36 pixel_loop: 37 mov byte [fs:di], bl 38 inc bl 39 inc di 40 cmp bl, 255 41 je endline 42 jmp pixel_loop 43 44 endline: 45 add di, 65 46 xor bl, bl 47 mov ax, di 48 cmp ax, (320*200) 49 je infinite_loop 50 jmp pixel_loop 51 52 ;;; For now, hang until the computer is rebooted. 53 infinite_loop: 54 jmp infinite_loop 55 56 ;;; Fill the remaining bytes with 0 and write a partition table 57 times 0x1b8-($-$$) db 0 58 db "ExOSxx" ;; 0x1b8 unique disk ID (4-6 bytes? Can be any value) 59 ;;; Partition table entries follow this format: 60 ;;; 1 byte Bootable flag (0x00 = no, 0x80 = yes) 61 ;;; 3 bytes Start Head Sector Cylinder (8 bits + 6 bits + 10 bits) 62 ;;; 1 byte Partition type (0x01 = FAT12) 63 ;;; 3 bytes End Head Sector Cylinder (8 bits + 6 bits + 10 bits) 64 ;;; 4 bytes LBA offset 65 ;;; 4 bytes LBA length 66 ;;;0x1be 0x1c1 0x1c2 0x1c5 0x1c6 0x1c9 0x1ca 0x1cd 67 ;;; This is filled with dummy values, and later patched with gdisk. 68 db 0x80, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xa0, 0x05, 0x00, 0x00, 0x53, 0x05, 0x00, 0x00 ;; 0x1be p1 69 db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ;; 0x1ce p2 70 db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ;; 0x1de p3 71 db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ;; 0x1ee p4 72 db 0x55, 0xaa ;; 0x1fe End the bootsector with 55 AA, which is the MBR signature. 73 74 ;;; This is the end of the first 512 bytes (the bootsector). 75 76 ;;; Leave some space for the GPT header and partition table entries (LBA0 = MBR, LBA1 = header, LBA2..33 = GPT partition tables) 77 times (34*512)-($-$$) db 0 78 79 ;;; The MS-DOS maximum line length is 8192 (excluding the \r\n), 80 ;;; but the GPT partition table is a bit more than 16384 bytes long. 81 ;;; We therefore inject in the Makefile intermediate \r\n in some 82 ;;; unused partition entries, after the disk image has been 83 ;;; partitioned using gdisk. 84 85 ;;; End of line for MS-DOS, so that it correctly processes the GOTO instruction 86 db 0x0d, 0x0a 87 ;;; For some reason, MS-DOS seems to ignore this line, so we leave an empty comment there. 88 db "::" 89 db 0x0d, 0x0a 90 db "@GOTO msdos", 0x0d, 0x0a 91 92 ;;; After the bootsector, close the sh here-document skipped via : <<'EOF' 93 db 0x0a 94 db "EOF", 0x0a 95 db "echo Hello world by the OS, from sh!", 0x0a 96 db "if test $# -ge 1 && test ", 0x22, "$1", 0x22, " = exit", 0x0a 97 db "then", 0x0a 98 db ":", 0x0a 99 db "else", 0x0a 100 db "while sleep 10", 0x0a, "do", 0x0a, ":", 0x0a, "done", 0x0a 101 db "fi", 0x0a 102 db "exit", 0x0a 103 ;;; for good measure: go into an infinite loop if the exit did not happen. 104 db "while :; do sleep 1; done", 0x0a 105 106 ;;; end of the SH section, everything until this point is skipped by MS-DOS batch due to the GOTO 107 ;;; End of line for MS-DOS, so that it correctly processes the :msdos label 108 db 0x0d, 0x0a 109 db ":msdos", 0x0d, 0x0a 110 db "@cls", 0x0d, 0x0a 111 db "@echo Hello world by the OS, from MS-DOS!", 0x0d, 0x0a 112 db "@GOTO %1 pause", 0x0d, 0x0a 113 db ":pause", 0x0d, 0x0a 114 db "@pause", 0x0d, 0x0a 115 db ":exit", 0x0d, 0x0a 116 db "@exit 0", 0x0d, 0x0a 117 ;;; for good measure: go into an infinite loop if the exit did not happen. 118 db ":loop", 0x0d, 0x0a 119 db "@GOTO loop", 0x0d, 0x0a 120 121 ;;; Fill up to 32k with 0. This constitutes the reserved first 32k at the beginning of an ISO9660 image. 122 times (32*1024)-($-$$) db 0