ms-dos: CR+LF line endings, avoid lines longer than 8192, add [pause|exit] argument to .bat and sh code

This commit is contained in:
Georges Dupéron 2018-07-28 02:22:07 +02:00
parent 1e431b3fe0
commit 85af2114c6
2 changed files with 49 additions and 10 deletions

View File

@ -258,6 +258,7 @@ ${os_filename}: build/os.32k build/os.iso build/os.fat12 build/os.zip.adjusted \
${dep_bytes_header_32k_size} \ ${dep_bytes_header_32k_size} \
${dep_bytes_fat12_start} \ ${dep_bytes_fat12_start} \
${dep_bytes_fat12_size} \ ${dep_bytes_fat12_size} \
${dep_bytes_gpt_mirror_start} \
${dep_bytes_gpt_mirror_end} \ ${dep_bytes_gpt_mirror_end} \
${dep_sectors_fat12_start} \ ${dep_sectors_fat12_start} \
${dep_sectors_fat12_size} \ ${dep_sectors_fat12_size} \
@ -287,6 +288,14 @@ ${os_filename}: build/os.32k build/os.iso build/os.fat12 build/os.zip.adjusted \
printf "1\nN\n"; \ printf "1\nN\n"; \
printf "01\nY\nN\n"; \ printf "01\nY\nN\n"; \
printf "p\no\nw\nY\n") | while read str; do echo "$$str"; printf "\033[1;33m%s\033[m\n" "$$str" >&2; sleep 0.01; done | gdisk $@ printf "p\no\nw\nY\n") | while read str; do echo "$$str"; printf "\033[1;33m%s\033[m\n" "$$str" >&2; sleep 0.01; done | gdisk $@
# Inject MS-DOS newlines (CR+LF) and comments (":: ") in the GUID field of unused partition table entries,
# so that the part that is to be skipped by MS-DOS does not form a line longer than the MS-DOS maximum
# line length (8192 excluding CR+LF). $i below is the partition entry number, starting from 1
# The numbers 55 and 118 are arbitrarily chosen so that the space between two CR+LF is less than 8192.
for i in 55 118; do \
printf "\r\n:: %02x" $$i | dd bs=1 seek=$$(( 1024 + ( ($$i) - 1) * 128 + 16)) count=7 conv=notrunc of=$@; \
printf "\r\n:: %02x" $$i | dd bs=1 seek=$$(( ${bytes_gpt_mirror_start} + ( ($$i) - 1) * 128 + 16)) count=7 conv=notrunc of=$@; \
done
# splice in zip at the end # splice in zip at the end
set -x; dd skip=${bytes_zip_start} seek=${bytes_zip_start} bs=1 conv=notrunc if=build/os.zip.adjusted of=$@ set -x; dd skip=${bytes_zip_start} seek=${bytes_zip_start} bs=1 conv=notrunc if=build/os.zip.adjusted of=$@
chmod a+x-w $@ chmod a+x-w $@

View File

@ -3,7 +3,17 @@
db "#!/usr/bin/env sh", 0x0a db "#!/usr/bin/env sh", 0x0a
db ": <<'EOF'", 0x0a db ": <<'EOF'", 0x0a
db "GOTO msdos", 0x0a ;;; Starting from here until EOF, all data is effectively ignored by Unix shells
;;; End of line for MS-DOS, so that it correctly processes the comment
db 0x0d, 0x0a
;;; The GOTO target must not be more than one block away (512 bytes by default
;;; on some systems) apparently, so it is impractical since the target is
;;; so far away in our case. Instead, we use a comment, but if there are some
;;; compatibility issues with the comment syntax, we could likely still use
;;; GOTO and insert intermediate jump points.
;; db "GOTO msdos", 0x0d, 0x0a
db ":: "
;;; The #!… above is interpreted as … jnz short 0x7c78 in x86 assembly. ;;; The #!… above is interpreted as … jnz short 0x7c78 in x86 assembly.
times 0x7c78-0x7c00-($-$$) db 0 times 0x7c78-0x7c00-($-$$) db 0
@ -66,24 +76,44 @@ db 0x55, 0xaa ;; 0x1fe End the bootsector with 55 AA, which is the MBR signatur
;;; Leave some space for the GPT header and partition table entries (LBA0 = MBR, LBA1 = header, LBA2..33 = GPT partition tables) ;;; Leave some space for the GPT header and partition table entries (LBA0 = MBR, LBA1 = header, LBA2..33 = GPT partition tables)
times (34*512)-($-$$) db 0 times (34*512)-($-$$) db 0
;;; The MS-DOS maximum line length is 8192 (excluding the \r\n),
;;; but the GPT partition table is a bit more than 16384 bytes long.
;;; We therefore inject in the Makefile intermediate \r\n in some
;;; unused partition entries, after the disk image has been
;;; partitioned using gdisk.
;;; End of line for MS-DOS, so that it correctly processes the GOTO instruction
db 0x0d, 0x0a
db "GOTO msdos", 0x0d, 0x0a
;;; After the bootsector, close the sh here-document skipped via : <<'EOF' ;;; After the bootsector, close the sh here-document skipped via : <<'EOF'
db 0x0a db 0x0a
db "EOF", 0x0a db "EOF", 0x0a
db "echo Hello world by the OS, from sh!", 0x0a db "echo Hello world by the OS, from sh!", 0x0a
db "while sleep 10; do :; done", 0x0a db "if test $# -ge 1 && test ", 0x22, "$1", 0x22, " = exit", 0x0a
db "then", 0x0a
db ":", 0x0a
db "else", 0x0a
db "while sleep 10", 0x0a, "do", 0x0a, ":", 0x0a, "done", 0x0a
db "fi", 0x0a
db "exit", 0x0a db "exit", 0x0a
;;; for good measure: go into an infinite loop if the exit did not happen. ;;; for good measure: go into an infinite loop if the exit did not happen.
db "while :; do sleep 1; done", 0x0a db "while :; do sleep 1; done", 0x0a
;;; end of the SH section, everything until this point is skipped by MS-DOS batch due to the GOTO' ;;; end of the SH section, everything until this point is skipped by MS-DOS batch due to the GOTO
db ":msdos", 0x0a ;;; End of line for MS-DOS, so that it correctly processes the :msdos label
db "@cls", 0x0a db 0x0d, 0x0a
db "@echo Hello world by the OS, from MS-DOS!", 0x0a db ":msdos", 0x0d, 0x0a
db "command.com", 0x0a db "@cls", 0x0d, 0x0a
db "exit", 0x0a db "echo Hello world by the OS, from MS-DOS!", 0x0d, 0x0a
db "@goto %1 :pause", 0x0d, 0x0a
db ":pause", 0x0d, 0x0a
db "@pause", 0x0d, 0x0a
db ":exit", 0x0d, 0x0a
db "@exit 0", 0x0d, 0x0a
;;; for good measure: go into an infinite loop if the exit did not happen. ;;; for good measure: go into an infinite loop if the exit did not happen.
db ":loop", 0x0a db ":loop", 0x0d, 0x0a
db "GOTO loop", 0x0a db "@GOTO loop", 0x0d, 0x0a
;;; Fill up to 32k with 0. This constitutes the reserved first 32k at the beginning of an ISO9660 image. ;;; Fill up to 32k with 0. This constitutes the reserved first 32k at the beginning of an ISO9660 image.
times (32*1024)-($-$$) db 0 times (32*1024)-($-$$) db 0