- Timestamp:
- Nov 20, 2023 4:16:55 PM (15 months ago)
- Location:
- trunk/src/VBox/ValidationKit/bootsectors
- Files:
-
- 5 added
- 17 edited
- 2 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/ValidationKit/bootsectors/Config.kmk
r102131 r102157 117 117 $1_SOURCES += $$($1_0_OUTDIR)/stub$2.asm 118 118 $1_CLEAN += $$($1_0_OUTDIR)/stub$2.asm 119 $$$$($1_0_OUTDIR)/stub$2.asm: $$(VBOX_PATH_BOOTSECTORS_SRC)/Config.kmk | $$$$(dir $$$$@) 119 #$$$$($1_0_OUTDIR)/stub$2.asm: $$(VBOX_PATH_BOOTSECTORS_SRC)/Config.kmk | $$$$(dir $$$$@) 120 $$$$($1_0_OUTDIR)/stub$2.asm: | $$$$(dir $$$$@) 120 121 $(QUIET)$(APPEND) -tn $$@ \ 121 122 '%include "bs3kit.mac"' \ … … 168 169 $1_SOURCES += $$($1_0_OUTDIR)/stub_$2$3.asm 169 170 $1_CLEAN += $$($1_0_OUTDIR)/stub_$2$3.asm 170 $$$$($1_0_OUTDIR)/stub_$2$3.asm: $$(VBOX_PATH_BOOTSECTORS_SRC)/Config.kmk | $$$$(dir $$$$@) 171 #$$$$($1_0_OUTDIR)/stub_$2$3.asm: $$(VBOX_PATH_BOOTSECTORS_SRC)/Config.kmk | $$$$(dir $$$$@) 172 $$$$($1_0_OUTDIR)/stub_$2$3.asm: | $$$$(dir $$$$@) 171 173 $(QUIET)$(APPEND) -tn $$@ \ 172 174 '%include "bs3kit.mac"' \ … … 407 409 # to rename intrinsic functions so they don't clash with the 16-bit compiler. 408 410 # 409 TOOL_Bs3Ow32 := OpenWatcom C/C++ 32-bit with object convertsion 410 TOOL_Bs3Ow32_CC = $(TOOL_OPENWATCOM_CC) 411 TOOL_Bs3Ow32_CXX = $(TOOL_OPENWATCOM_CXX) 411 TOOL_Bs3Ow32 := OpenWatcom C/C++ 32-bit with object conversion and import library creation 412 TOOL_Bs3Ow32_EXTENDS = OPENWATCOM 413 TOOL_Bs3Ow32_CC = $(TOOL_OPENWATCOM_CC) 414 TOOL_Bs3Ow32_CXX = $(TOOL_OPENWATCOM_CXX) 412 415 TOOL_Bs3Ow32_COBJSUFF = .o32 413 416 TOOL_Bs3Ow32_CFLAGS = $(TOOL_OPENWATCOM_CFLAGS) … … 470 473 # to rename intrinsic functions so they don't clash with the 16-bit compiler. 471 474 # 472 TOOL_Bs3Ow16 := OpenWatcom C/C++ 16-bit with object convertsion 473 TOOL_Bs3Ow16_CC = $(TOOL_OPENWATCOM-16_CC) 474 TOOL_Bs3Ow16_CXX = $(TOOL_OPENWATCOM-16_CXX) 475 TOOL_Bs3Ow16 := OpenWatcom C/C++ 16-bit with object convertsion 476 TOOL_Bs3Ow16_EXTENDS := OPENWATCOM-16 477 TOOL_Bs3Ow16_CC = $(TOOL_OPENWATCOM-16_CC) 478 TOOL_Bs3Ow16_CXX = $(TOOL_OPENWATCOM-16_CXX) 475 479 TOOL_Bs3Ow16_COBJSUFF = .o16 476 480 TOOL_Bs3Ow16_CFLAGS = $(TOOL_OPENWATCOM-16_CFLAGS) … … 523 527 endef 524 528 529 TOOL_Bs3Ow16_AR = $(TOOL_OPENWATCOM_AR) 530 TOOL_Bs3Ow16_ARFLAGS = $(TOOL_OPENWATCOM_ARFLAGS) @@replace-me-with-list-option@@ 531 TOOL_Bs3Ow16_ARLIBSUFF = $(TOOL_OPENWATCOM_ARLIBSUFF) 532 TOOL_Bs3Ow16_LINK_LIBRARY_OUTPUT = $(outbase)-implib.lib $(outbase)-implib.rsp $(outbase).lst 533 TOOL_Bs3Ow16_LINK_LIBRARY_OUTPUT_MAYBE_PRECIOUS = $(TOOL_OPENWATCOM_LINK_LIBRARY_OUTPUT_MAYBE_PRECIOUS) 534 TOOL_Bs3Ow16_LINK_LIBRARY_OUTPUT_DEPEND = $(TOOL_OPENWATCOM_LINK_LIBRARY_OUTPUT_DEPEND) 535 TOOL_Bs3Ow16_LINK_LIBRARY_OUTPUT_DEPORD = $(TOOL_OPENWATCOM_LINK_LIBRARY_OUTPUT_DEPORD) 536 define TOOL_Bs3Ow16_LINK_LIBRARY_CMDS 537 $(subst @@replace-me-with-list-option@@,-l=$(call TOOL_OPENWATCOM_FIX_SLASHES,$(outbase).lst),$(TOOL_OPENWATCOM_LINK_LIBRARY_CMDS)) 538 $(TOOL_Bs3Ow16_AR) -m "$(out)" \ 539 | $(SED) \ 540 -e '/^ _Bs3[_a-zA-Z0-9]*$$(DOLLAR)/!d' \ 541 -e '/_EndProc/d' \ 542 -e '/\./d' \ 543 -e 's/^ *\(_Bs3[_a-zA-Z0-9]*\)$$(DOLLAR)/++\1.bs3kit/' \ 544 --output $(outbase)-implib.rsp 545 $(TOOL_Bs3Ow16_AR) -q -n -io -inn $(call TOOL_OPENWATCOM_FIX_SLASHES,$(outbase)-implib.lib) @$(outbase)-implib.rsp 546 endef 547 525 548 # Debug info format depends on what we use for 64-bit. 526 549 if 1 #1of ($(KBUILD_HOST), win) - wlink dwarf .sym files are useless for binary blobs … … 550 573 local type := C64 551 574 $(kb-src-one 2) 575 endef 576 577 define VBoxBs3KitImgSrcHandler_high_dll 578 local genasm := $($(target)_0_OUTDIR)/high-dll-$(notdir $(basename $(source))).asm 579 $(eval $(target)_CLEAN += $(genasm)) 580 $(eval $(target)_GEN_SOURCES_ += $(genasm)) 581 $(target)_2_VBOX_BS3KIT_HIGH_DLLS := $($(target)_2_VBOX_BS3KIT_HIGH_DLLS) $(source) 582 583 $(genasm): $(source) | $(VBoxBs3Linker_1_TARGET) $$(dir $$@) 584 $(VBoxBs3Linker_1_TARGET) --generate-high-dll-import-table "$<" --output "$@" 552 585 endef 553 586 … … 609 642 .c16:VBoxBs3KitImgSrcHandler_16bit_c \ 610 643 .c32:VBoxBs3KitImgSrcHandler_32bit_c \ 611 .c64:VBoxBs3KitImgSrcHandler_64bit_c 644 .c64:VBoxBs3KitImgSrcHandler_64bit_c \ 645 .high-dll:VBoxBs3KitImgSrcHandler_high_dll 612 646 TEMPLATE_VBoxBS3KitImg_ASOBJSUFF = .o16 613 647 TEMPLATE_VBoxBS3KitImg_ASTOOL = VBoxNasm … … 620 654 TEMPLATE_VBoxBS3KitImg_DEFS.debug = BS3_STRICT 621 655 622 TEMPLATE_VBoxBS3KitImg_ARTOOL = OPENWATCOM-16656 TEMPLATE_VBoxBS3KitImg_ARTOOL = Bs3Ow16 623 657 624 658 TEMPLATE_VBoxBS3KitImg_CTOOL = Bs3Ow16 … … 738 772 segment BS3TEXT64_START \ 739 773 segment BS3TEXT64 \ 740 segment BS3TEXT64_END 774 segment BS3TEXT64_END \ 775 clname BS3HIGHDLLCLASS \ 776 segment BS3HIGHDLLEXPORTS \ 777 segment BS3HIGHDLLIMPORTS \ 778 segment BS3HIGHDLLSTRINGS \ 779 segment BS3HIGHDLLTABLE \ 780 segment BS3HIGHDLLTABLE_END 741 781 742 782 TEMPLATE_VBoxBS3KitImg_LNK_DEPS = \ … … 745 785 TEMPLATE_VBoxBS3KitImg_POST_CMDS = $(if $(eq $(tool_do),LINK_LIBRARY) \ 746 786 ,,$(QUIET)$(MV_EXT) -f -- "$(out)" "$(out).tmp" \ 747 $$(NLTAB)$(QUIET)$(VBoxBs3Linker_1_TARGET) -o $(out) $(bs3-bootsector_1_TARGET) $(out).tmp \787 $$(NLTAB)$(QUIET)$(VBoxBs3Linker_1_TARGET) -o $(out) $(bs3-bootsector_1_TARGET) $(out).tmp $($(target)_2_VBOX_BS3KIT_HIGH_DLLS) \ 748 788 $$(NLTAB)$(QUIET)$(RM_EXT) -f -- "$(out).tmp") \ 749 789 $(eval .PRECIOUS: $(outbase).map) # ugly hack! 750 751 790 752 791 TEMPLATE_VBoxBS3KitImg_LIBS = \ … … 778 817 $(PATH_OBJ)/bs3kit-lm64/bs3kit-lm64.lib 779 818 819 # Variant of VBoxBS3KitImg that's for images needing large 32-bit and 64-bit 820 # code segments. 821 TEMPLATE_VBoxBS3KitImgBig = Template for building BS3Kit test images with high 32-bit & 64-bit code 822 TEMPLATE_VBoxBS3KitImgBig_EXTENDS = VBoxBS3KitImg 823 TEMPLATE_VBoxBS3KitImgBig_DEFS = $(TEMPLATE_VBoxBS3KitImg_DEFS) BS3_BIG_IMAGE BS3_TEXT32_ABOVE_1M BS3_TEXT64_ABOVE_1M 824 #TEMPLATE_VBoxBS3KitImgBig_LDFLAGS = \ 825 # $(subst BS3CLASS32CODE, BS3CLASS32CODE segaddr=0xa000$(SP), $(TEMPLATE_VBoxBS3KitImg_LDFLAGS)) 826 #TEMPLATE_VBoxBS3KitImgBig_POST_CMDS = $(NO_SUCH_VARIABLE) 827 828 # BS3Kit template for a high image. 829 TEMPLATE_VBoxBS3KitHighImg = Template for building BS3Kit test images, the high DLL. 830 TEMPLATE_VBoxBS3KitHighImg_EXTENDS := VBoxBS3KitImg 831 TEMPLATE_VBoxBS3KitHighImg_DEFS = $(TEMPLATE_VBoxBS3KitImg_DEFS) BS3_IS_HIGH_IMAGE 832 TEMPLATE_VBoxBS3KitHighImg_ASFLAGS = $(filter-out -g,$(TEMPLATE_VBoxBS3KitImg_ASFLAGS)) # trouble with bs3-cpu-basic-3, nasm produce garbage comment/something. 833 TEMPLATE_VBoxBS3KitHighImg_BINSUFF := .high-dll 834 TEMPLATE_VBoxBS3KitHighImg_LDTOOL := OPENWATCOM-WL 835 TEMPLATE_VBoxBS3KitHighImg_LDFLAGS := system os2v2 flat dll \ 836 \ 837 segment BS3TEXT16 executeread \ 838 segment BS3TEXT16_NEARSTUBS executeread \ 839 segment BS3TEXT16_FARSTUBS executeread \ 840 segment BS3TEXT16_END executeread \ 841 \ 842 $(if-expr "$(BS3KIT_SEGNM_DATA16)" == "", \ 843 segment BS3DATA16 readwrite \ 844 segment BS3DATA16_DATA readwrite \ 845 segment DATA readwrite \ 846 segment _DATA readwrite \ 847 segment BS3DATA16CONST readwrite \ 848 segment CONST readwrite \ 849 segment BS3DATA16CONST2 readwrite \ 850 segment CONST2 readwrite \ 851 segment STRINGS readwrite \ 852 segment BSS readwrite \ 853 segment _BSS readwrite \ 854 segment BS3DATA16_END readwrite \ 855 , \ 856 segment BS3DATA16 readwrite \ 857 segment BS3DATA16CONST readwrite \ 858 segment BS3DATA16CONST2 readwrite \ 859 segment BS3DATA16_DATA readwrite \ 860 segment BS3DATA16_END readwrite \ 861 ) \ 862 \ 863 segment BS3TEXT32 executeonly \ 864 segment BS3TEXT32_END executeonly \ 865 \ 866 segment BS3DATA32 readwrite \ 867 segment BS3DATA32CONST readwrite \ 868 segment BS3DATA32CONST2 readwrite \ 869 segment BS3DATA32_DATA readwrite \ 870 segment BS3DATA32_BSS readwrite \ 871 segment BS3DATA32_END readwrite \ 872 \ 873 segment BS3TEXT64 executeread \ 874 segment BS3TEXT64_END executeread \ 875 \ 876 segment BS3DATA64 readwrite \ 877 segment BS3DATA64CONST readwrite \ 878 segment BS3DATA64_BSS readwrite \ 879 segment BS3DATA64_END readwrite \ 880 \ 881 debug $(BS3_OW_DBG_LDOPT) all \ 882 \ 883 option quiet, map, statics, verbose, symfile, objalign=4096, offset=0x800000 \ 884 disable 1014, 1080 885 886 TEMPLATE_VBoxBS3KitHighImg_LIBS = \ 887 $(PATH_OBJ)/bs3kit-common-16/bs3kit-common-16-implib.lib \ 888 $(PATH_OBJ)/bs3kit-common-32/bs3kit-common-32-implib.lib \ 889 $(PATH_OBJ)/bs3kit-common-64/bs3kit-common-64-implib.lib \ 890 \ 891 $(PATH_OBJ)/bs3kit-pe16/bs3kit-pe16-implib.lib \ 892 $(PATH_OBJ)/bs3kit-pe16_32/bs3kit-pe16_32-implib.lib \ 893 $(PATH_OBJ)/bs3kit-pe32/bs3kit-pe32-implib.lib \ 894 $(PATH_OBJ)/bs3kit-pe32_16/bs3kit-pe32_16-implib.lib \ 895 $(PATH_OBJ)/bs3kit-pev86/bs3kit-pev86-implib.lib \ 896 $(PATH_OBJ)/bs3kit-pp16/bs3kit-pp16-implib.lib \ 897 $(PATH_OBJ)/bs3kit-pp16_32/bs3kit-pp16_32-implib.lib \ 898 $(PATH_OBJ)/bs3kit-pp32/bs3kit-pp32-implib.lib \ 899 $(PATH_OBJ)/bs3kit-pp32_16/bs3kit-pp32_16-implib.lib \ 900 $(PATH_OBJ)/bs3kit-pae16/bs3kit-pae16-implib.lib \ 901 $(PATH_OBJ)/bs3kit-pae16_32/bs3kit-pae16_32-implib.lib \ 902 $(PATH_OBJ)/bs3kit-pae32/bs3kit-pae32-implib.lib \ 903 $(PATH_OBJ)/bs3kit-pae32_16/bs3kit-pae32_16-implib.lib \ 904 $(PATH_OBJ)/bs3kit-lm16/bs3kit-lm16-implib.lib \ 905 $(PATH_OBJ)/bs3kit-lm32/bs3kit-lm32-implib.lib \ 906 $(PATH_OBJ)/bs3kit-lm64/bs3kit-lm64-implib.lib 907 908 TEMPLATE_VBoxBS3KitHighImg_POST_CMDS = $(NO_SUCH_VARIABLE) 909 780 910 # BS3Kit template for 32-bit code. 781 911 TEMPLATE_VBoxBS3KitImg32 = Template for building BS3Kit test images. … … 791 921 TEMPLATE_VBoxBS3KitImg32_DEFS = ARCH_BITS=32 IN_BS3KIT 792 922 TEMPLATE_VBoxBS3KitImg32_DEFS.debug = BS3_STRICT 793 TEMPLATE_VBoxBS3KitImg32_ARTOOL = OPENWATCOM923 TEMPLATE_VBoxBS3KitImg32_ARTOOL = Bs3Ow16 794 924 TEMPLATE_VBoxBS3KitImg32_CTOOL = Bs3Ow32 795 925 TEMPLATE_VBoxBS3KitImg32_CXXTOOL = Bs3Ow32 … … 814 944 TEMPLATE_VBoxBS3KitImg64_DEFS = IN_BS3KIT ARCH_BITS=64 815 945 TEMPLATE_VBoxBS3KitImg64_DEFS.debug = BS3_STRICT 816 TEMPLATE_VBoxBS3KitImg64_ARTOOL = OPENWATCOM946 TEMPLATE_VBoxBS3KitImg64_ARTOOL = Bs3Ow16 817 947 TEMPLATE_VBoxBS3KitImg64_INCS = $(VBOX_PATH_BS3KIT_SRC) . 818 948 if1of ($(KBUILD_HOST), win) -
trunk/src/VBox/ValidationKit/bootsectors/Makefile.kmk
r102134 r102157 276 276 # CPU basics #3 (first being bootsector2-cpu-basic-1). 277 277 MISCBINS += bs3-cpu-basic-3 278 bs3-cpu-basic-3_TEMPLATE = VBoxBS3KitImg 278 bs3-cpu-basic-3_TEMPLATE = VBoxBS3KitImgBig 279 279 bs3-cpu-basic-3_INCS = . 280 280 bs3-cpu-basic-3_DEFS = BS3_CMN_INSTANTIATE_FILE1=bs3-cpu-basic-3-cmn-template.c … … 286 286 bs3kit/bs3-cmn-instantiate.c32 \ 287 287 bs3kit/bs3-cmn-instantiate.c64 \ 288 bs3-cpu-basic-3-asm.asm 288 bs3-cpu-basic-3-asm.asm \ 289 $(bs3-cpu-basic-3-high_1_TARGET) 289 290 bs3-cpu-basic-3-cmn-template.o:: \ 290 291 $$(bs3-cpu-basic-3_0_OUTDIR)/bs3kit/bs3-cmn-instantiate-x0.o16 \ … … 292 293 $$(bs3-cpu-basic-3_0_OUTDIR)/bs3kit/bs3-cmn-instantiate.o64 \ 293 294 $$(bs3-cpu-basic-3_0_OUTDIR)/bs3-cpu-basic-3-asm.o16 295 296 MISCBINS += bs3-cpu-basic-3-high 297 bs3-cpu-basic-3-high_TEMPLATE = VBoxBS3KitHighImg 298 bs3-cpu-basic-3-high_INCS = . 299 bs3-cpu-basic-3-high_SOURCES = \ 300 bs3kit/bs3-first-high-image.asm \ 301 bs3-cpu-basic-3-high-asm.asm 294 302 295 303 # -
trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-basic-3-asm.asm
r102134 r102157 1 1 ; $Id$ 2 2 ;; @file 3 ; BS3Kit - bs3-cpu-basic- 23 ; BS3Kit - bs3-cpu-basic-3 4 4 ; 5 5 -
trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-basic-3-cmn-template.c
r102134 r102157 65 65 pfnWorker32(); 66 66 } 67 #else 68 for (i = 0; i < 64; i++) 69 BS3_CMN_FAR_NM(bs3CpuBasic3_lea_64)(); 70 #endif 67 71 return 0; 68 #else69 //for (i = 0; i < 64; i++)70 // BS3_CMN_FAR_NM(bs3CpuBasic3_lea_64)71 RT_NOREF(i);72 return BS3TESTDOMODE_SKIPPED;73 #endif74 72 } 75 73 -
trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-basic-3-cmn-template.mac
r102134 r102157 44 44 TMPL_BEGIN_TEXT 45 45 46 47 ;********************************************************************************************************************************* 48 ;* External Symbols * 49 ;********************************************************************************************************************************* 50 extern _Bs3Text16_StartOfSegment 46 51 47 52 … … 59 64 %define LEA_EDI 077777177h 60 65 66 %define LEA_RAX 01111111111111110h 67 %define LEA_RCX 02222222222222202h 68 %define LEA_RDX 03333333333333033h 69 %define LEA_RBX 04444444444440444h 70 %define LEA_RSP 058595a5d51525356h 71 %define LEA_RBP 05555555555555551h 72 %define LEA_RSI 06666666666666616h 73 %define LEA_RDI 07777777777777177h 74 %define LEA_R8 08888888888881888h 75 %define LEA_R9 09999999999999992h 76 %define LEA_R10 0aaaaaaaaaaaaaa2ah 77 %define LEA_R11 0bbbbbbbbbbbbb2bbh 78 %define LEA_R12 0cccccccccccc2ccch 79 %define LEA_R13 0ddddddddddddddd3h 80 %define LEA_R14 0eeeeeeeeeeeeee3eh 81 %define LEA_R15 0fffffffffffff3ffh 82 83 84 61 85 ; 62 86 ; Switching segment for the 16-bit stuff, this may need some space. … … 67 91 TMPL_BEGIN_TEXT 68 92 %endif 69 70 71 ;;72 ; Loads known values into all registers but xSP.73 BS3_PROC_BEGIN_CMN bs3CpuBasic3_lea_load_regs, BS3_PBC_NEAR74 %if TMPL_BITS == 6475 mov rax, 01111111111111110h76 mov rcx, 02222222222222202h77 mov rdx, 03333333333333033h78 mov rbx, 04444444444440444h79 mov rbp, 05555555555555551h80 mov rsi, 06666666666666616h81 mov rdi, 07777777777777177h82 mov r8, 08888888888881888h83 mov r9, 09999999999999992h84 mov r10, 0aaaaaaaaaaaaaa2ah85 mov r11, 0bbbbbbbbbbbbb2bbh86 mov r12, 0cccccccccccc2ccch87 mov r13, 0ddddddddddddddd3h88 mov r14, 0eeeeeeeeeeeeee3eh89 mov r15, 0fffffffffffff3ffh90 %else91 mov eax, LEA_EAX92 mov ecx, LEA_ECX93 mov edx, LEA_EDX94 mov ebx, LEA_EBX95 mov ebp, LEA_EBP96 mov esi, LEA_ESI97 mov edi, LEA_EDI98 %endif99 BS3_HYBRID_RET100 BS3_PROC_END_CMN bs3CpuBasic3_lea_16_load_regs101 93 102 94 … … 108 100 %define BS3CPUBASIC3_LEA_16_MACROS 109 101 %macro test_lea_16_one 3 110 call BS3_CMN_NM(bs3CpuBasic3_lea_load_regs)102 call .load_regs 111 103 lea strict %1, strict %2 112 104 cmp %1, %3 & 0ffffh … … 162 154 popad 163 155 BS3_HYBRID_RET 156 157 .load_regs: 158 mov eax, LEA_EAX 159 mov ecx, LEA_ECX 160 mov edx, LEA_EDX 161 mov ebx, LEA_EBX 162 mov ebp, LEA_EBP 163 mov esi, LEA_ESI 164 mov edi, LEA_EDI 165 ret 164 166 BS3_PROC_END_CMN bs3CpuBasic3_lea_16 165 167 … … 452 454 BS3_PROC_END_CMN bs3CpuBasic3_lea_32 453 455 454 %endif ; TMPL_BITS != 64 456 457 %else ; TMPL_BITS == 64 458 459 460 ;; 461 ; Tests 64-bit addressing using the LEA instruction. 462 ; 463 BS3_PROC_BEGIN_CMN bs3CpuBasic3_lea_64, BS3_PBC_FAR 464 push rax 465 push rcx 466 push rdx 467 push rbx 468 push rbp 469 push rsi 470 push rdi 471 push r8 472 push r9 473 push r10 474 push r11 475 push r12 476 push r13 477 push r14 478 push r15 479 .test_label: 480 mov [BS3_DATA16_WRT(BS3_DATA_NM(g_bs3CpuBasic3_lea_rsp))], rsp 481 482 ; 483 ; Loop thru all the modr/m memory encodings. 484 ; 485 %assign iMod 0 486 %assign iDstReg 0 ; We don't test all destination registers 487 %rep 3 488 %rep 16 ; Destination registers per encoding. Testing all takes too much space. 489 %assign iMemReg 0 490 %rep 16 491 %assign iDstReg_Value %sel(iDstReg+1, LEA_RAX, LEA_RCX, LEA_RDX, LEA_RBX, LEA_RSP, LEA_RBP, LEA_RSI, LEA_RDI, \ 492 LEA_R8, LEA_R9, LEA_R10, LEA_R11, LEA_R12, LEA_R13, LEA_R14, LEA_R15) 493 494 %if (iMemReg & 7) == 4 495 ; 496 ; SIB. 497 ; 498 %assign iBase 0 499 %rep 16 500 %if (iBase & 7) == 5 && iMod == 0 501 %assign iBase_Value 0 502 %else 503 %assign iBase_Value %sel(iBase+1, LEA_RAX, LEA_RCX, LEA_RDX, LEA_RBX, LEA_RSP, LEA_RBP, LEA_RSI, LEA_RDI, \ 504 LEA_R8, LEA_R9, LEA_R10, LEA_R11, LEA_R12, LEA_R13, LEA_R14, LEA_R15) 505 %endif 506 507 %assign iIndex 0 508 %assign cShift 0 ; we don't have enough room for checking all the shifts. 509 %rep 16 510 %assign iBase_Value %sel(iIndex+1, LEA_RAX, LEA_RCX, LEA_RDX, LEA_RBX, 0, LEA_RBP, LEA_RSI, LEA_RDI, \ 511 LEA_R8, LEA_R9, LEA_R10, LEA_R11, LEA_R12, LEA_R13, LEA_R14, LEA_R15) 512 513 ; 514 ; We don't test all shift combinations, there just isn't enough space 515 ; in the image for that. 516 ; 517 %assign cShiftLoops 0 ; Disabled for now 518 %rep cShiftLoops 519 %error asdf 520 ; 521 ; LEA+SIB w/ 64-bit operand size and 64-bit address size. 522 ; 523 call .load_regs 524 %if iBase == 4 || iDstReg == 4 525 mov rsp, LEA_RSP 526 %endif 527 528 ; lea 529 %assign iValue iBase_Value + (iIndex_Value << cShift) 530 db X86_OP_REX_W | ((iBase & 8) >> 3) | ((iIndex & 8) >> 2) | ((iDstReg) & 8 >> 1) 531 db 8dh, X86_MODRM_MAKE(iMod, iDstReg & 7, iMemReg & 7), X86_SIB_MAKE(iBase & 7, iIndex & 7, cShift) 532 %if iMod == X86_MOD_MEM1 533 db -128 534 %assign iValue iValue - 128 535 %elif iMod == X86_MOD_MEM4 || (iMod == 0 && iBase == 5) 536 dd -07fffffffh 537 %assign iValue iValue - 07fffffffh 538 %endif 539 540 ; cmp iDstReg, iValue 541 %if iValue <= 07fffffffh && iValue >= -080000000h 542 db X86_OP_REX_W | ((iDstReg & 8) >> 3) 543 db 81h, X86_MODRM_MAKE(X86_MOD_REG, 7, iDstReg & 7) 544 dd iValue & 0ffffffffh 545 %elif iDstReg != X86_GREG_xAX 546 mov rax, iValue 547 db X86_OP_REX_W | ((iDstReg & 8) >> 3) 548 db 39h, X86_MODRM_MAKE(X86_MOD_REG, X86_GREG_xAX, iDstReg & 7) 549 %else 550 mov rcx, iValue 551 cmp rax, rcx 552 %endif 553 %if iDstReg == 4 554 mov rsp, [BS3_DATA16_WRT(BS3_DATA_NM(g_bs3CpuBasic3_lea_rsp))] 555 %endif 556 jz $+3 557 int3 558 %assign cShift (cShift + 1) & 3 559 560 %endrep 561 %assign iIndex iIndex + 1 562 %endrep 563 %assign iBase iBase + 1 564 %endrep 565 566 %else ; !SIB 567 ; 568 ; Plain lea reg, [reg] with disp according to iMod, 569 ; or lea reg, [disp32] if iMemReg == 5 && iMod == 0. 570 ; 571 %if (iMemReg & 7) == 5 && iMod == 0 572 %assign iMemReg_Value 0 573 %else 574 %assign iMemReg_Value %sel(iMemReg+1, LEA_RAX, LEA_RCX, LEA_RDX, LEA_RBX, LEA_RSP, LEA_RBP, LEA_RSI, LEA_RDI, \ 575 LEA_R8, LEA_R9, LEA_R10, LEA_R11, LEA_R12, LEA_R13, LEA_R14, LEA_R15) 576 %endif 577 578 ; 579 ; 64-bit operand and address size first. 580 ; 581 call .load_regs 582 %if iDstReg == 4 583 mov rsp, LEA_RSP 584 %endif 585 586 ; lea 587 %assign iValue iMemReg_Value 588 db X86_OP_REX_W | ((iDstReg & 8) >> 1) | ((iMemReg & 8) >> 3) 589 db 8dh, X86_MODRM_MAKE(iMod, iDstReg & 7, iMemReg & 7) 590 %if iMod == X86_MOD_MEM1 591 db 39 592 %assign iValue iValue + 39 593 %elif iMod == 0 && (iMemReg & 7) == 5 594 dd .load_regs - $ - 4 595 %elif iMod == X86_MOD_MEM4 596 dd 058739af8h 597 %assign iValue iValue + 058739af8h 598 %endif 599 600 ; cmp iDstReg, iValue 601 %if (iValue <= 07fffffffh && iValue >= -080000000h) || (iMod == 0 && (iMemReg & 7) == 5) 602 db X86_OP_REX_W | ((iDstReg & 8) >> 3) 603 db 81h, X86_MODRM_MAKE(X86_MOD_REG, 7, iDstReg & 7) 604 %if iMod == 0 && (iMemReg & 7) == 5 605 dd .load_regs wrt BS3FLAT 606 %else 607 dd iValue & 0ffffffffh 608 %endif 609 %else 610 %if iDstReg != iMemReg && iValue == iMemReg_Value ; This isn't entirely safe, but it saves a bit of space. 611 db X86_OP_REX_W | ((iDstReg & 8) >> 1) | ((iMemReg & 8) >> 3) 612 db 39h, X86_MODRM_MAKE(X86_MOD_REG, iDstReg & 7, iMemReg & 7) 613 %elif iDstReg != X86_GREG_xAX 614 mov rax, iValue 615 db X86_OP_REX_W | ((iDstReg & 8) >> 3) 616 db 39h, X86_MODRM_MAKE(X86_MOD_REG, X86_GREG_xAX, iDstReg & 7) 617 %else 618 mov rcx, iValue 619 cmp rax, rcx 620 %endif 621 %endif 622 %if iDstReg == 4 623 mov rsp, [BS3_DATA16_WRT(BS3_DATA_NM(g_bs3CpuBasic3_lea_rsp))] 624 %endif 625 jz $+3 626 int3 627 628 ; 629 ; 64-bit operand and 32-bit address size. 630 ; 631 call .load_regs 632 %if iDstReg == 4 633 mov rsp, LEA_RSP 634 %endif 635 636 ; lea 637 %assign iValue iMemReg_Value 638 db X86_OP_PRF_SIZE_ADDR 639 db X86_OP_REX_W | ((iDstReg & 8) >> 1) | ((iMemReg & 8) >> 3) 640 db 8dh, X86_MODRM_MAKE(iMod, iDstReg & 7, iMemReg & 7) 641 %if iMod == X86_MOD_MEM1 642 db -92 643 %assign iValue iValue - 92 644 %elif iMod == 0 && (iMemReg & 7) == 5 645 dd .test_label - $ - 4 646 %elif iMod == X86_MOD_MEM4 647 dd -038f8acf3h 648 %assign iValue iValue - 038f8acf3h 649 %endif 650 %assign iValue iValue & 0ffffffffh 651 652 ; cmp iDstReg, iValue 653 %if (iValue <= 07fffffffh && iValue >= 0) || (iMod == 0 && (iMemReg & 7) == 5) 654 db X86_OP_REX_W | ((iDstReg & 8) >> 3) 655 db 81h, X86_MODRM_MAKE(X86_MOD_REG, 7, iDstReg & 7) 656 %if iMod == 0 && (iMemReg & 7) == 5 657 dd .test_label wrt BS3FLAT 658 %else 659 dd iValue 660 %endif 661 %else 662 %if iDstReg != X86_GREG_xAX 663 mov eax, iValue 664 db X86_OP_REX_W | ((iDstReg & 8) >> 3) 665 db 39h, X86_MODRM_MAKE(X86_MOD_REG, X86_GREG_xAX, iDstReg & 7) 666 %else 667 mov ecx, iValue 668 cmp rax, rcx 669 %endif 670 %endif 671 %if iDstReg == 4 672 mov rsp, [BS3_DATA16_WRT(BS3_DATA_NM(g_bs3CpuBasic3_lea_rsp))] 673 %endif 674 jz $+3 675 int3 676 677 ; 678 ; 32-bit operand and 64-bit address size. 679 ; 680 call .load_regs 681 %if iDstReg == 4 682 mov rsp, LEA_RSP 683 %endif 684 685 ; lea 686 %assign iValue iMemReg_Value 687 %if iDstReg >= 8 || iMemReg >= 8 688 db X86_OP_REX | ((iDstReg & 8) >> 1) | ((iMemReg & 8) >> 3) 689 %endif 690 db 8dh, X86_MODRM_MAKE(iMod, iDstReg & 7, iMemReg & 7) 691 %if iMod == X86_MOD_MEM1 692 db 16 693 %assign iValue iValue + 16 694 %elif iMod == 0 && (iMemReg & 7) == 5 695 dd .load_regs - $ - 4 696 %elif iMod == X86_MOD_MEM4 697 dd 0596829deh 698 %assign iValue iValue + 0596829deh 699 %endif 700 %assign iValue iValue & 0ffffffffh 701 702 ; cmp iDstReg, iValue 703 %if (iValue <= 07fffffffh && iValue >= 0) || (iMod == 0 && (iMemReg & 7) == 5) 704 db X86_OP_REX_W | ((iDstReg & 8) >> 3) 705 db 81h, X86_MODRM_MAKE(X86_MOD_REG, 7, iDstReg & 7) 706 %if iMod == 0 && (iMemReg & 7) == 5 707 dd .load_regs wrt BS3FLAT 708 %else 709 dd iValue 710 %endif 711 %else 712 %if iDstReg != X86_GREG_xAX 713 mov eax, iValue 714 db X86_OP_REX_W | ((iDstReg & 8) >> 3) 715 db 39h, X86_MODRM_MAKE(X86_MOD_REG, X86_GREG_xAX, iDstReg & 7) 716 %else 717 mov ecx, iValue 718 cmp rax, rcx 719 %endif 720 %endif 721 %if iDstReg == 4 722 mov rsp, [BS3_DATA16_WRT(BS3_DATA_NM(g_bs3CpuBasic3_lea_rsp))] 723 %endif 724 jz $+3 725 int3 726 727 ; 728 ; 16-bit operand and 64-bit address size. 729 ; 730 call .load_regs 731 %if iDstReg == 4 732 mov rsp, LEA_RSP 733 %endif 734 735 ; lea 736 %assign iValue iMemReg_Value 737 db X86_OP_PRF_SIZE_OP 738 %if iDstReg >= 8 || iMemReg >= 8 739 db X86_OP_REX | ((iDstReg & 8) >> 1) | ((iMemReg & 8) >> 3) 740 %endif 741 db 8dh, X86_MODRM_MAKE(iMod, iDstReg & 7, iMemReg & 7) 742 %if iMod == X86_MOD_MEM1 743 db -16 744 %assign iValue iValue - 16 745 %elif iMod == 0 && (iMemReg & 7) == 5 746 dd _Bs3Text16_StartOfSegment - $ - 4 + 7 wrt BS3FLAT 747 %assign iValue 7 748 %elif iMod == X86_MOD_MEM4 749 dd 075682332h 750 %assign iValue iValue + 075682332h 751 %endif 752 %assign iValue (iValue & 0ffffh) | (iDstReg_Value & 0ffffffffffff0000h) 753 754 ; cmp iDstReg, iValue 755 %if (iValue <= 07fffffffh && iValue >= -080000000h) 756 db X86_OP_REX_W | ((iDstReg & 8) >> 3) 757 db 81h, X86_MODRM_MAKE(X86_MOD_REG, 7, iDstReg & 7) 758 dd iValue 759 %elif iDstReg != X86_GREG_xAX 760 mov rax, iValue 761 db X86_OP_REX_W | ((iDstReg & 8) >> 3) 762 db 39h, X86_MODRM_MAKE(X86_MOD_REG, X86_GREG_xAX, iDstReg & 7) 763 %else 764 mov rcx, iValue 765 cmp rax, rcx 766 %endif 767 %if iDstReg == 4 768 mov rsp, [BS3_DATA16_WRT(BS3_DATA_NM(g_bs3CpuBasic3_lea_rsp))] 769 %endif 770 jz $+3 771 int3 772 773 ; 774 ; 16-bit operand and 32-bit address size. 775 ; 776 call .load_regs 777 %if iDstReg == 4 778 mov rsp, LEA_RSP 779 %endif 780 781 ; lea 782 %assign iValue iMemReg_Value 783 db X86_OP_PRF_SIZE_OP 784 db X86_OP_PRF_SIZE_ADDR 785 %if iDstReg >= 8 || iMemReg >= 8 786 db X86_OP_REX | ((iDstReg & 8) >> 1) | ((iMemReg & 8) >> 3) 787 %endif 788 db 8dh, X86_MODRM_MAKE(iMod, iDstReg & 7, iMemReg & 7) 789 %if iMod == X86_MOD_MEM1 790 db 99 791 %assign iValue iValue + 99 792 %elif iMod == 0 && (iMemReg & 7) == 5 793 dd _Bs3Text16_StartOfSegment - $ - 4 + 3347 wrt BS3FLAT 794 %assign iValue 3347 795 %elif iMod == X86_MOD_MEM4 796 dd -075623432h 797 %assign iValue iValue - 075623432h 798 %endif 799 %assign iValue (iValue & 0ffffh) | (iDstReg_Value & 0ffffffffffff0000h) 800 801 ; cmp iDstReg, iValue 802 %if (iValue <= 07fffffffh && iValue >= -080000000h) 803 db X86_OP_REX_W | ((iDstReg & 8) >> 3) 804 db 81h, X86_MODRM_MAKE(X86_MOD_REG, 7, iDstReg & 7) 805 dd iValue 806 %elif iDstReg != X86_GREG_xAX 807 mov rax, iValue 808 db X86_OP_REX_W | ((iDstReg & 8) >> 3) 809 db 39h, X86_MODRM_MAKE(X86_MOD_REG, X86_GREG_xAX, iDstReg & 7) 810 %else 811 mov rcx, iValue 812 cmp rax, rcx 813 %endif 814 %if iDstReg == 4 815 mov rsp, [BS3_DATA16_WRT(BS3_DATA_NM(g_bs3CpuBasic3_lea_rsp))] 816 %endif 817 jz $+3 818 int3 819 820 %endif ; !SIB 821 %assign iMemReg iMemReg + 1 822 %endrep 823 %assign iDstReg (iDstReg + 1) & 15 824 %endrep 825 %assign iMod iMod + 1 826 %endrep 827 828 mov rsp, [BS3_DATA16_WRT(BS3_DATA_NM(g_bs3CpuBasic3_lea_rsp))] 829 pop r15 830 pop r14 831 pop r13 832 pop r12 833 pop r11 834 pop r10 835 pop r9 836 pop r8 837 pop rdi 838 pop rsi 839 pop rbp 840 pop rbx 841 pop rdx 842 pop rcx 843 pop rax 844 ret 845 846 .load_regs: 847 mov rax, LEA_RAX 848 mov rcx, LEA_RCX 849 mov rdx, LEA_RDX 850 mov rbx, LEA_RBX 851 mov rbp, LEA_RBP 852 mov rsi, LEA_RSI 853 mov rdi, LEA_RDI 854 mov r8, LEA_R8 855 mov r9, LEA_R9 856 mov r10, LEA_R10 857 mov r11, LEA_R11 858 mov r12, LEA_R12 859 mov r13, LEA_R13 860 mov r14, LEA_R14 861 mov r15, LEA_R15 862 ret 863 BS3_PROC_END_CMN bs3CpuBasic3_lea_64 864 865 %endif ; TMPL_BITS == 64 455 866 456 867 -
trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-basic-3.c
r102130 r102157 64 64 BS3_DECL(void) Main_rm() 65 65 { 66 Bs3InitAll _rm();66 Bs3InitAllWithHighDlls_rm(); 67 67 Bs3TestInit("bs3-cpu-basic-3"); 68 68 Bs3TestPrintf("g_uBs3CpuDetected=%#x\n", g_uBs3CpuDetected); -
trunk/src/VBox/ValidationKit/bootsectors/bs3kit/Makefile.kmk
r102127 r102157 42 42 # Boot Sector post-link tool (used via the parent Config.kmk). 43 43 BLDPROGS += VBoxBs3Linker 44 VBoxBs3Linker_TEMPLATE = VBox BldProg44 VBoxBs3Linker_TEMPLATE = VBoxAdvBldProg 45 45 VBoxBs3Linker_SOURCES = $(VBOX_PATH_BS3KIT_SRC)/VBoxBs3Linker.cpp 46 46 … … 204 204 bs3-cmn-SlabAlloc.c \ 205 205 bs3-cmn-SlabAllocEx.c \ 206 bs3-cmn-SlabAllocFixed.c \ 206 207 bs3-cmn-SlabFree.c \ 207 208 bs3-cmn-SlabListInit.c \ … … 299 300 bs3-system-data.asm \ 300 301 bs3-rm-InitAll.c \ 302 bs3-rm-InitAllWithHighDlls.c \ 301 303 bs3-rm-InitMemory.c \ 302 304 bs3-rm-InitGdt.c \ 305 bs3-rm-InitHighDlls.c \ 303 306 bs3-cmn-hexdigits.c \ 304 307 bs3-cmn-CpuDetectData.c \ … … 370 373 # 371 374 VBOX_BS3KIT_MODE_SOURCES = \ 375 bs3-mode-MemCopyFlat.asm \ 372 376 bs3-mode-Name.asm \ 373 377 bs3-mode-NameShortLower.asm \ … … 408 412 bs3-mode-TestDoModesByMax.c \ 409 413 bs3-mode-TestDoModesHlp.asm \ 410 bs3-mode-BiosInt15hE820.asm 414 bs3-mode-BiosInt15hE820.asm \ 415 bs3-mode-DiskQueryGeometry.asm \ 416 bs3-mode-DiskRead.asm 411 417 412 418 # The 16-bit real mode BS3Kit library. -
trunk/src/VBox/ValidationKit/bootsectors/bs3kit/VBoxBs3Linker.cpp
r99632 r102157 40 40 *********************************************************************************************************************************/ 41 41 #include <stdio.h> 42 #include <string.h>43 42 #include <stdlib.h> 44 #include <iprt/types.h> 43 45 44 #include <iprt/assert.h> 45 #include <iprt/err.h> 46 #include <iprt/file.h> 47 #include <iprt/getopt.h> 48 #include <iprt/initterm.h> 49 #include <iprt/ldr.h> 50 #include <iprt/mem.h> 51 #include <iprt/message.h> 52 #include <iprt/path.h> 53 #include <iprt/string.h> 54 55 #include "bs3kit-linker.h" 46 56 47 57 … … 49 59 * Structures and Typedefs * 50 60 *********************************************************************************************************************************/ 51 #pragma pack(1) 52 typedef struct BS3BOOTSECTOR 53 { 54 uint8_t abJmp[3]; 55 char abOemId[8]; 56 /** @name EBPB, DOS 4.0 style. 57 * @{ */ 58 uint16_t cBytesPerSector; /**< 00bh */ 59 uint8_t cSectorsPerCluster; /**< 00dh */ 60 uint16_t cReservedSectors; /**< 00eh */ 61 uint8_t cFATs; /**< 010h */ 62 uint16_t cRootDirEntries; /**< 011h */ 63 uint16_t cTotalSectors; /**< 013h */ 64 uint8_t bMediaDescriptor; /**< 015h */ 65 uint16_t cSectorsPerFAT; /**< 016h */ 66 uint16_t cPhysSectorsPerTrack; /**< 018h */ 67 uint16_t cHeads; /**< 01ah */ 68 uint32_t cHiddentSectors; /**< 01ch */ 69 uint32_t cLargeTotalSectors; /**< 020h - We (ab)use this to indicate the number of sectors to load. */ 70 uint8_t bBootDrv; /**< 024h */ 71 uint8_t bFlagsEtc; /**< 025h */ 72 uint8_t bExtendedSignature; /**< 026h */ 73 uint32_t dwSerialNumber; /**< 027h */ 74 char abLabel[11]; /**< 02bh */ 75 char abFSType[8]; /**< 036h */ 76 /** @} */ 77 } BS3BOOTSECTOR; 78 #pragma pack() 79 typedef BS3BOOTSECTOR *PBS3BOOTSECTOR; 80 81 AssertCompileMemberOffset(BS3BOOTSECTOR, cLargeTotalSectors, 0x20); 82 AssertCompileMemberOffset(BS3BOOTSECTOR, abLabel, 0x2b); 83 AssertCompileMemberOffset(BS3BOOTSECTOR, abFSType, 0x36); 84 85 #define BS3_OEMID "BS3Kit\n\n" 86 #define BS3_FSTYPE "RawCode\n" 87 #define BS3_LABEL "VirtualBox\n" 88 #define BS3_MAX_SIZE UINT32_C(491520) /* 480KB */ 89 90 91 int main(int argc, char **argv) 92 { 93 const char *pszOutput = NULL; 94 struct BS3LNKINPUT 95 { 96 const char *pszFile; 97 FILE *pFile; 98 uint32_t cbFile; 99 } *paInputs = (struct BS3LNKINPUT *)calloc(sizeof(paInputs[0]), argc); 100 unsigned cInputs = 0; 101 uint32_t cSectors = 0; 102 61 typedef struct BS3LNKINPUT 62 { 63 const char *pszFile; 64 FILE *pFile; 65 uint32_t cbFile; 66 uint32_t cbBits; 67 uint32_t uLoadAddr; 68 uint32_t offInImage; 69 void *pvBits; 70 RTLDRMOD hLdrMod; 71 } BS3LNKINPUT; 72 73 74 typedef struct BS3LNKIMPORTSTATE 75 { 76 FILE *pOutput; 77 RTSTRSPACE hImportNames; 78 unsigned cImports; 79 unsigned cExports; 80 size_t cbStrings; 81 } BS3LNKIMPORTSTATE; 82 83 typedef struct BS3LNKIMPORTNAME 84 { 85 RTSTRSPACECORE Core; 86 size_t offString; 87 RT_FLEXIBLE_ARRAY_EXTENSION 88 char szName[RT_FLEXIBLE_ARRAY]; 89 } BS3LNKIMPORTNAME; 90 91 92 93 /** 94 * @callback_method_impl{FNRTLDRENUMSYMS} 95 */ 96 static DECLCALLBACK(int) GenerateHighDllAsmOutputExportTable(RTLDRMOD hLdrMod, const char *pszSymbol, unsigned uSymbol, 97 RTLDRADDR Value, void *pvUser) 98 { 99 BS3LNKIMPORTSTATE * const pState = (BS3LNKIMPORTSTATE *)pvUser; 100 if (!pszSymbol || !*pszSymbol) 101 return RTMsgErrorRc(VERR_LDR_BAD_FIXUP, "All exports must be by name. uSymbol=%#x Value=%RX64", uSymbol, (uint64_t)Value); 102 103 // BS3HIGHDLLEXPORTENTRY 104 fprintf(pState->pOutput, 105 "g_pfn%s:\n" 106 " dd 0\n" 107 " dd %#08x\n", 108 pszSymbol, (unsigned)pState->cbStrings); 109 pState->cbStrings += strlen(pszSymbol) + 1; 110 pState->cExports += 1; 111 112 RT_NOREF(hLdrMod); 113 return VINF_SUCCESS; 114 } 115 116 /** 117 * @callback_method_impl{FNRTSTRSPACECALLBACK} 118 */ 119 static DECLCALLBACK(int) GenerateHighDllAsmOutputImportTable(PRTSTRSPACECORE pStr, void *pvUser) 120 { 121 FILE *pOutput = (FILE *)pvUser; 122 BS3LNKIMPORTNAME *pName = (BS3LNKIMPORTNAME *)pStr; 123 124 // BS3HIGHDLLIMPORTENTRY 125 fprintf(pOutput, 126 " dw %#06x\n" 127 " dw seg %s\n" 128 " dd %s wrt BS3FLAT\n" 129 , (unsigned)pName->offString, pName->szName, pName->szName); 130 131 return VINF_SUCCESS; 132 } 133 134 135 /** 136 * @callback_method_impl{FNRTLDRENUMSYMS} 137 */ 138 static DECLCALLBACK(int) GenerateHighDllAsmOutputExportStrings(RTLDRMOD hLdrMod, const char *pszSymbol, unsigned uSymbol, 139 RTLDRADDR Value, void *pvUser) 140 { 141 BS3LNKIMPORTSTATE * const pState = (BS3LNKIMPORTSTATE *)pvUser; 142 if (!pszSymbol || !*pszSymbol) 143 return RTMsgErrorRc(VERR_LDR_BAD_FIXUP, "All exports must be by name. uSymbol=%#x Value=%RX64", uSymbol, (uint64_t)Value); 144 145 fprintf(pState->pOutput, " db '%s', 0\n", pszSymbol); 146 pState->cbStrings += strlen(pszSymbol) + 1; 147 148 RT_NOREF(hLdrMod); 149 return VINF_SUCCESS; 150 } 151 152 153 /** 154 * @callback_method_impl{FNRTSTRSPACECALLBACK} 155 */ 156 static DECLCALLBACK(int) GenerateHighDllAsmOutputImportStrings(PRTSTRSPACECORE pStr, void *pvUser) 157 { 158 BS3LNKIMPORTSTATE * const pState = (BS3LNKIMPORTSTATE *)pvUser; 159 BS3LNKIMPORTNAME * const pName = (BS3LNKIMPORTNAME *)pStr; 160 161 pName->offString = pState->cbStrings; 162 fprintf(pState->pOutput, " db '%s', 0\n", pName->szName); 163 pState->cbStrings += pName->Core.cchString + 1; 164 165 return VINF_SUCCESS; 166 } 167 168 169 /** 170 * @callback_method_impl{FNRTLDRIMPORT} 171 */ 172 static DECLCALLBACK(int) GenerateHighDllAsmImportCallback(RTLDRMOD hLdrMod, const char *pszModule, const char *pszSymbol, 173 unsigned uSymbol, PRTLDRADDR pValue, void *pvUser) 174 { 175 BS3LNKIMPORTSTATE *pState = (BS3LNKIMPORTSTATE *)pvUser; 176 if (!pszSymbol) 177 return RTMsgErrorRc(VERR_LDR_BAD_FIXUP, "All imports must be by name. pszModule=%s uSymbol=%#x", pszModule, uSymbol); 178 if (!RTStrSpaceGet(&pState->hImportNames, pszSymbol)) 179 { 180 size_t const cchSymbol = strlen(pszSymbol); 181 BS3LNKIMPORTNAME * const pName = (BS3LNKIMPORTNAME *)RTMemAlloc(RT_UOFFSETOF_DYN(BS3LNKIMPORTNAME, 182 szName[cchSymbol + 1])); 183 AssertReturn(pName, VERR_NO_MEMORY); 184 185 pName->Core.cchString = cchSymbol; 186 pName->Core.pszString = (char *)memcpy(pName->szName, pszSymbol, cchSymbol + 1); 187 pName->offString = UINT16_MAX; 188 189 AssertReturnStmt(RTStrSpaceInsert(&pState->hImportNames, &pName->Core), RTMemFree(pName), 190 RTMsgErrorRc(VERR_INTERNAL_ERROR, "IPE #1")); 191 pState->cImports++; 192 } 193 *pValue = 0x10042; 194 RT_NOREF(hLdrMod); 195 return VINF_SUCCESS; 196 } 197 198 199 static RTEXITCODE GenerateHighDllImportTableAssembly(FILE *pOutput, const char *pszGenAsmFor) 200 { 201 RTERRINFOSTATIC ErrInfo; 202 RTLDRMOD hLdrMod; 203 int rc = RTLdrOpenEx(pszGenAsmFor, 0, RTLDRARCH_X86_32, &hLdrMod, RTErrInfoInitStatic(&ErrInfo)); 204 if (RT_FAILURE(rc)) 205 return RTMsgErrorExitFailure("RTLdrOpenEx failed to open '%s': %Rrc%#RTeim", pszGenAsmFor, rc, &ErrInfo.Core); 206 207 RTEXITCODE rcExit; 208 size_t cbImage = RTLdrSize(hLdrMod); 209 if (cbImage != ~(size_t)0) 210 { 211 void *pvBits = RTMemAlloc(cbImage); 212 if (pvBits) 213 { 214 BS3LNKIMPORTSTATE State = { pOutput, NULL, 0, 0, 0 }; 215 rc = RTLdrGetBits(hLdrMod, pvBits, BS3HIGHDLL_LOAD_ADDRESS, GenerateHighDllAsmImportCallback, pOutput); 216 if (RT_SUCCESS(rc)) 217 { 218 /** @todo move more of this to bs3kit*.h? */ 219 fprintf(pOutput, 220 ";\n" 221 "; Automatically generated - DO NOT MODIFY!\n" 222 ";\n" 223 "%%include \"bs3kit.mac\"\n" 224 "\n" 225 "section BS3HIGHDLLEXPORTS align=4 CLASS=BS3HIGHDLLCLASS PUBLIC USE32 FLAT\n" 226 "section BS3HIGHDLLIMPORTS align=4 CLASS=BS3HIGHDLLCLASS PUBLIC USE32 FLAT\n" 227 "section BS3HIGHDLLSTRINGS align=4 CLASS=BS3HIGHDLLCLASS PUBLIC USE32 FLAT\n" 228 "section BS3HIGHDLLTABLE align=4 CLASS=BS3HIGHDLLCLASS PUBLIC USE32 FLAT\n" 229 "section BS3HIGHDLLTABLE_END align=4 CLASS=BS3HIGHDLLCLASS PUBLIC USE32 FLAT\n" 230 "GROUP BS3HIGHDLLGROUP BS3HIGHDLLIMPORTS BS3HIGHDLLEXPORTS BS3HIGHDLLSTRINGS BS3HIGHDLLTABLE BS3HIGHDLLTABLE_END\n" 231 "\n"); 232 233 /* Populate the string table with imports. */ 234 const char *pszFilename = RTPathFilename(pszGenAsmFor); 235 fprintf(pOutput, 236 "section BS3HIGHDLLSTRINGS\n" 237 "start_strings:\n" 238 " db 0\n" 239 " db '%s', 0 ; module name\n" 240 " ; imports\n", 241 pszFilename); 242 State.cbStrings = 1 + strlen(pszFilename) + 1; 243 rc = RTStrSpaceEnumerate(&State.hImportNames, GenerateHighDllAsmOutputImportStrings, &State); 244 AssertRC(rc); 245 fprintf(pOutput, " ; exports\n"); 246 247 /* Populate the string table with exports. */ 248 size_t const offExportStrings = State.cbStrings; 249 rc = RTLdrEnumSymbols(hLdrMod, 0, pvBits, BS3HIGHDLL_LOAD_ADDRESS, GenerateHighDllAsmOutputExportStrings, &State); 250 size_t const cbStrings = State.cbStrings; 251 if (RT_SUCCESS(rc) && cbStrings < _64K) 252 { 253 /* Output the import table. */ 254 fprintf(pOutput, 255 "section BS3HIGHDLLIMPORTS\n" 256 "start_imports:\n"); 257 rc = RTStrSpaceEnumerate(&State.hImportNames, GenerateHighDllAsmOutputImportTable, &State); 258 AssertRC(rc); 259 fprintf(pOutput, "\n"); 260 261 /* Output the export table (ASSUMES stable enumeration order). */ 262 fprintf(pOutput, 263 "section BS3HIGHDLLEXPORTS\n" 264 "start_exports:\n"); 265 State.cbStrings = offExportStrings; 266 rc = RTLdrEnumSymbols(hLdrMod, 0, pvBits, BS3HIGHDLL_LOAD_ADDRESS, GenerateHighDllAsmOutputExportTable, &State); 267 AssertRC(rc); 268 fprintf(pOutput, "\n"); 269 270 /* Generate the table entry. */ 271 fprintf(pOutput, 272 "section BS3HIGHDLLTABLE\n" 273 "start_entry: ; struct BS3HIGHDLLENTRY \n" 274 " db '%s', 0 ; achMagic[8]\n" 275 " dd 0 ; uLoadAddress\n" 276 " dd %#08zx ; cbLoaded\n" 277 " dd 0 ; offInImage\n" 278 " dd %#08zx ; cbInImage\n" 279 " dd %#04x ; cImports\n" 280 " dd start_imports - start_entry\n" 281 " dd %#04x ; cExports\n" 282 " dd start_exports - start_entry\n" 283 " dd %#05x ; cbStrings\n" 284 " dd start_strings - start_entry\n" 285 " dd 1 ; offDllName\n" 286 , BS3HIGHDLLENTRY_MAGIC, cbImage, cbImage, State.cImports, State.cExports, (unsigned)cbStrings); 287 rcExit = RTEXITCODE_SUCCESS; 288 } 289 else if (RT_FAILURE(rc)) 290 rcExit = RTMsgErrorExitFailure("RTLdrEnumSymbols failed: %Rrc", rc); 291 else 292 rcExit = RTMsgErrorExitFailure("Too many import/export strings: %#x bytes, max 64KiB", cbStrings); 293 } 294 else 295 rcExit = RTMsgErrorExitFailure("RTLdrGetBits failed: %Rrc", rc); 296 RTMemFree(pvBits); 297 } 298 else 299 rcExit = RTMsgErrorExitFailure("Out of memory!"); 300 } 301 else 302 rcExit = RTMsgErrorExitFailure("RTLdrSize failed on '%s'", pszGenAsmFor); 303 304 RTLdrClose(hLdrMod); 305 return rcExit; 306 } 307 308 309 static BS3HIGHDLLENTRY *LocateHighDllEntry(uint8_t const *pbBits, uint32_t cbBits, const char *pszFilename) 310 { 103 311 /* 104 * Scan the arguments.312 * We search backwards for up to 4 KB. 105 313 */ 106 for (int i = 1; i < argc; i++) 107 { 108 if (argv[i][0] == '-') 314 size_t const offStop = cbBits > _4K ? cbBits - _4K : 0; 315 size_t off = cbBits >= sizeof(BS3HIGHDLLENTRY) ? cbBits - sizeof(BS3HIGHDLLENTRY) : 0; 316 while (off > offStop) 317 { 318 BS3HIGHDLLENTRY const *pEntry = (BS3HIGHDLLENTRY const *)&pbBits[off]; 319 if ( pEntry->achMagic[0] == BS3HIGHDLLENTRY_MAGIC[0] 320 && memcmp(pEntry->achMagic, BS3HIGHDLLENTRY_MAGIC, sizeof(pEntry->achMagic)) == 0) 109 321 { 110 const char *pszOpt = &argv[i][1]; 111 if (*pszOpt == '-') 322 if (pEntry->cbStrings < _64K && pEntry->cbStrings >= 8) 112 323 { 113 /* Convert long options to short ones. */ 114 pszOpt--; 115 if (!strcmp(pszOpt, "--output")) 116 pszOpt = "o"; 117 else if (!strcmp(pszOpt, "--version")) 118 pszOpt = "V"; 119 else if (!strcmp(pszOpt, "--help")) 120 pszOpt = "h"; 121 else 324 if (off + pEntry->offStrings > 0 && off + pEntry->offStrings + pEntry->cbStrings <= off) 122 325 { 123 fprintf(stderr, "syntax errro: Unknown options '%s'\n", pszOpt); 124 free(paInputs); 125 return 2; 126 } 127 } 128 129 /* Process the list of short options. */ 130 while (*pszOpt) 131 { 132 switch (*pszOpt++) 133 { 134 case 'o': 326 if (off + pEntry->offExports > 0 && off + pEntry->offExports + pEntry->cExports * 8 <= off) 135 327 { 136 const char *pszValue = pszOpt; 137 pszOpt = strchr(pszOpt, '\0'); 138 if (*pszValue == '=') 139 pszValue++; 140 else if (!*pszValue) 328 if (off + pEntry->offImports > 0 && off + pEntry->offImports + pEntry->cImports * 8 <= off) 141 329 { 142 if ( i + 1 >= argc)330 if (pEntry->offFilename > 0 && pEntry->offFilename < pEntry->cbStrings) 143 331 { 144 fprintf(stderr, "syntax error: The --output option expects a filename.\n");145 free(paInputs);146 return 12;332 const char *psz = (const char *)&pbBits[off + pEntry->offStrings + pEntry->offFilename]; 333 if (strcmp(pszFilename, psz) == 0) 334 return (BS3HIGHDLLENTRY *)pEntry; 147 335 } 148 pszValue = argv[++i];149 336 } 150 if (pszOutput)151 {152 fprintf(stderr, "Only one output file is allowed. You've specified '%s' and '%s'\n",153 pszOutput, pszValue);154 free(paInputs);155 return 2;156 }157 pszOutput = pszValue;158 pszOpt = "";159 break;160 337 } 161 162 case 'V':163 printf("%s\n", "$Revision$");164 free(paInputs);165 return 0;166 167 case '?':168 case 'h':169 printf("usage: %s [options] -o <output> <input1> [input2 ... [inputN]]\n",170 argv[0]);171 free(paInputs);172 return 0;173 338 } 174 339 } 175 340 } 341 off--; 342 } 343 RTMsgError("Failed to find the BS3HIGHDLLENTRY structure for '%s'!", pszFilename); 344 return NULL; 345 } 346 347 348 /** 349 * @callback_method_impl{FNRTLDRIMPORT} 350 */ 351 static DECLCALLBACK(int) ResolveHighDllImportCallback(RTLDRMOD hLdrMod, const char *pszModule, const char *pszSymbol, 352 unsigned uSymbol, PRTLDRADDR pValue, void *pvUser) 353 { 354 BS3HIGHDLLENTRY * const pEntry = (BS3HIGHDLLENTRY *)pvUser; 355 if (!pszSymbol) 356 return RTMsgErrorRc(VERR_LDR_BAD_FIXUP, "All imports must be by name. pszModule=%s uSymbol=%#x", pszModule, uSymbol); 357 358 /* Search the import table: */ 359 BS3HIGHDLLIMPORTENTRY const *paImports = (BS3HIGHDLLIMPORTENTRY const *)((uintptr_t)pEntry + pEntry->offImports); 360 const char * const pszzStrings = (const char *)((uintptr_t)pEntry + pEntry->offStrings); 361 size_t i = pEntry->cImports; 362 while (i-- > 0) 363 { 364 if (strcmp(pszSymbol, &pszzStrings[paImports[i].offName]) == 0) 365 { 366 *pValue = paImports[i].offFlat; 367 return VINF_SUCCESS; 368 } 369 } 370 RT_NOREF(hLdrMod); 371 return RTMsgErrorRc(VERR_SYMBOL_NOT_FOUND, "Unable to locate import %s (in %s)!", pszSymbol, pszModule); 372 } 373 374 375 static RTEXITCODE DoTheLinking(FILE *pOutput, BS3LNKINPUT *paInputs, unsigned cInputs) 376 { 377 if (cInputs < 2) 378 return RTMsgErrorExitFailure("Require at least two input files when linking!"); 379 380 /* 381 * Read all the files into memory. 382 * 383 * The first two are binary blobs, i.e. the boot sector and the base image. 384 * Any additional files are DLLs and we need to do linking. 385 */ 386 uint32_t uHiLoadAddr = BS3HIGHDLL_LOAD_ADDRESS; 387 uint32_t off = 0; 388 for (unsigned i = 0; i < cInputs; i++) 389 { 390 paInputs[i].offInImage = off; 391 if (i < 2) 392 { 393 paInputs[i].cbBits = RT_ALIGN_32(paInputs[i].cbFile, 512); 394 paInputs[i].pvBits = RTMemAllocZ(paInputs[i].cbBits); 395 if (!paInputs[i].pvBits) 396 return RTMsgErrorExitFailure("Out of memory (%#x)\n", paInputs[i].cbBits); 397 size_t cbRead = fread(paInputs[i].pvBits, sizeof(uint8_t), paInputs[i].cbFile, paInputs[i].pFile); 398 if (cbRead != paInputs[i].cbFile) 399 return RTMsgErrorExitFailure("Error reading '%s' (got %d bytes, wanted %u).", 400 paInputs[i].pszFile, (int)cbRead, (unsigned)paInputs[i].cbFile); 401 paInputs[i].uLoadAddr = i == 90 ? 0x7c00 : 0x10000; 402 } 176 403 else 177 404 { 178 /* 179 * Add to input file collection. 180 */ 181 paInputs[cInputs].pszFile = argv[i]; 182 #if defined(RT_OS_OS2) || defined(RT_OS_WINDOWS) 183 FILE *pFile = fopen(paInputs[cInputs].pszFile, "rb"); 184 #else 185 FILE *pFile = fopen(paInputs[cInputs].pszFile, "r"); 186 #endif 187 if (pFile) 405 RTERRINFOSTATIC ErrInfo; 406 int rc = RTLdrOpenEx(paInputs[i].pszFile, 0, RTLDRARCH_X86_32, &paInputs[i].hLdrMod, RTErrInfoInitStatic(&ErrInfo)); 407 if (RT_FAILURE(rc)) 408 return RTMsgErrorExitFailure("RTLdrOpenEx failed to open '%s': %Rrc%#RTeim", 409 paInputs[i].pszFile, rc, &ErrInfo.Core); 410 411 size_t const cbImage = RTLdrSize(paInputs[i].hLdrMod); 412 if (cbImage == ~(size_t)0) 413 return RTMsgErrorExitFailure("RTLdrSize failed on '%s'!", paInputs[i].pszFile); 414 if (cbImage > _64M) 415 return RTMsgErrorExitFailure("Image '%s' is definitely too large: %#zx", paInputs[i].pszFile, cbImage); 416 417 paInputs[i].cbBits = RT_ALIGN_32((uint32_t)cbImage, 4096); /* Bs3InitHighDlls_rm depend on the 4KiB alignment. */ 418 paInputs[i].pvBits = RTMemAllocZ(paInputs[i].cbBits); 419 if (!paInputs[i].pvBits) 420 return RTMsgErrorExitFailure("Out of memory (%#x)\n", paInputs[i].cbBits); 421 422 /* Locate the entry for this high dll in the base image. */ 423 BS3HIGHDLLENTRY *pHighDllEntry = LocateHighDllEntry((uint8_t *)paInputs[1].pvBits, paInputs[1].cbFile, 424 RTPathFilename(paInputs[i].pszFile)); 425 AssertReturn(pHighDllEntry, RTEXITCODE_FAILURE); 426 427 /* Get the fixed up image bits. */ 428 rc = RTLdrGetBits(paInputs[i].hLdrMod, paInputs[i].pvBits, uHiLoadAddr, ResolveHighDllImportCallback, pHighDllEntry); 429 if (RT_FAILURE(rc)) 430 return RTMsgErrorExitFailure("RTLdrGetBits failed on '%s': %Rrc", paInputs[i].pszFile, rc); 431 432 /* Update the export addresses. */ 433 BS3HIGHDLLEXPORTENTRY *paExports = (BS3HIGHDLLEXPORTENTRY *)((uintptr_t)pHighDllEntry + pHighDllEntry->offExports); 434 const char * const pszzStrings = (const char *)((uintptr_t)pHighDllEntry + pHighDllEntry->offStrings); 435 size_t iExport = pHighDllEntry->cExports; 436 while (iExport-- > 0) 188 437 { 189 if (fseek(pFile, 0, SEEK_END) == 0) 190 { 191 paInputs[cInputs].cbFile = (uint32_t)ftell(pFile); 192 if (fseek(pFile, 0, SEEK_SET) == 0) 193 { 194 if (cInputs != 0 || paInputs[cInputs].cbFile == 512) 195 { 196 cSectors += RT_ALIGN_32(paInputs[cInputs].cbFile, 512) / 512; 197 if (cSectors <= BS3_MAX_SIZE / 512) 198 { 199 if (cSectors > 0) 200 { 201 paInputs[cInputs].pFile = pFile; 202 pFile = NULL; 203 } 204 else 205 fprintf(stderr, "error: empty input file: '%s'\n", paInputs[cInputs].pszFile); 206 } 207 else 208 fprintf(stderr, "error: input is too big: %u bytes, %u sectors (max %u bytes, %u sectors)\n" 209 "info: detected loading '%s'\n", 210 cSectors * 512, cSectors, BS3_MAX_SIZE, BS3_MAX_SIZE / 512, 211 paInputs[cInputs].pszFile); 212 } 213 else 214 fprintf(stderr, "error: first input file (%s) must be exactly 512 bytes\n", paInputs[cInputs].pszFile); 215 } 216 else 217 fprintf(stderr, "error: seeking to start of '%s' failed\n", paInputs[cInputs].pszFile); 218 } 438 const char * const pszSymbol = (const char *)&pszzStrings[paExports[iExport].offName]; 439 RTLDRADDR Value = 0; 440 rc = RTLdrGetSymbolEx(paInputs[i].hLdrMod, paInputs[i].pvBits, uHiLoadAddr, UINT32_MAX, pszSymbol, &Value); 441 if (RT_SUCCESS(rc)) 442 paExports[iExport].offFlat = (uint32_t)Value; 219 443 else 220 fprintf(stderr, "error: seeking to end of '%s' failed\n", paInputs[cInputs].pszFile);444 return RTMsgErrorExitFailure("Failed to resolve '%s' in '%s': %Rrc", pszSymbol, paInputs[i].pszFile, rc); 221 445 } 222 else 223 fprintf(stderr, "error: Failed to open input file '%s' for reading\n", paInputs[cInputs].pszFile); 224 if (pFile) 225 { 226 free(paInputs); 227 fclose(pFile); 228 return 1; 229 } 230 cInputs++; 446 447 /* Update the DLL entry with the load address and file address: */ 448 pHighDllEntry->offInImage = off; 449 pHighDllEntry->uLoadAddr = uHiLoadAddr; 450 paInputs[i].uLoadAddr = uHiLoadAddr; 451 uHiLoadAddr += paInputs[i].cbBits; 231 452 } 232 } 233 234 if (!pszOutput) 235 { 236 fprintf(stderr, "syntax error: No output file was specified (-o or --output).\n"); 237 free(paInputs); 238 return 2; 239 } 240 if (cInputs == 0) 241 { 242 fprintf(stderr, "syntax error: No input files was specified.\n"); 243 free(paInputs); 244 return 2; 245 } 453 Assert(!(off & 0x1ff)); 454 off += paInputs[i].cbBits; 455 Assert(!(off & 0x1ff)); 456 } 457 458 /** @todo image size check. */ 246 459 247 460 /* 248 * Do the job.461 * Patch the BPB with base image sector count. 249 462 */ 250 /* Open the output file. */ 251 #if defined(RT_OS_OS2) || defined(RT_OS_WINDOWS) 252 FILE *pOutput = fopen(pszOutput, "wb"); 253 #else 254 FILE *pOutput = fopen(pszOutput, "w"); 255 #endif 256 if (!pOutput) 257 { 258 fprintf(stderr, "error: Failed to open output file '%s' for writing\n", pszOutput); 259 free(paInputs); 260 return 1; 261 } 262 263 /* Copy the input files to the output file, with sector padding applied. */ 264 int rcExit = 0; 265 size_t off = 0; 266 for (unsigned i = 0; i < cInputs && rcExit == 0; i++) 267 { 268 uint8_t abBuf[4096]; /* Must be multiple of 512! */ 269 uint32_t cbToRead = paInputs[i].cbFile; 270 while (cbToRead > 0) 271 { 272 /* Read a block from the input file. */ 273 uint32_t const cbThisRead = RT_MIN(cbToRead, sizeof(abBuf)); 274 size_t cbRead = fread(abBuf, sizeof(uint8_t), cbThisRead, paInputs[i].pFile); 275 if (cbRead != cbThisRead) 276 { 277 fprintf(stderr, "error: Error reading '%s' (got %d bytes, wanted %u).\n", 278 paInputs[i].pszFile, (int)cbRead, (unsigned)cbThisRead); 279 rcExit = 1; 280 break; 281 } 282 cbToRead -= cbThisRead; 283 284 /* Padd the end of the file if necessary. */ 285 if ((cbRead & 0x1ff) != 0) 286 { 287 memset(&abBuf[cbRead], 0, 4096 - cbRead); 288 cbRead = (cbRead + 0x1ff) & ~0x1ffU; 289 } 290 291 /* Patch the BPB of the first file. */ 292 if (off == 0) 293 { 294 PBS3BOOTSECTOR pBs = (PBS3BOOTSECTOR)&abBuf[0]; 295 if ( memcmp(pBs->abLabel, RT_STR_TUPLE(BS3_LABEL)) == 0 296 && memcmp(pBs->abFSType, RT_STR_TUPLE(BS3_FSTYPE)) == 0 297 && memcmp(pBs->abOemId, RT_STR_TUPLE(BS3_OEMID)) == 0) 298 pBs->cLargeTotalSectors = cSectors; 299 else 300 { 301 fprintf(stderr, "error: Didn't find magic strings in the first file (%s).\n", paInputs[i].pszFile); 302 rcExit = 1; 303 } 304 } 305 306 /* Write the block to the output file. */ 307 if (fwrite(abBuf, sizeof(uint8_t), cbRead, pOutput) == cbRead) 308 off += cbRead; 309 else 310 { 311 fprintf(stderr, "error: fwrite failed\n"); 312 rcExit = 1; 313 break; 314 } 315 } 316 317 if (ferror(paInputs[i].pFile)) 318 { 319 fprintf(stderr, "error: Error reading '%s'.\n", paInputs[i].pszFile); 320 rcExit = 1; 321 } 322 } 323 324 /* Close the input files. */ 325 for (unsigned i = 0; i < cInputs && rcExit == 0; i++) 326 fclose(paInputs[i].pFile); 327 free(paInputs); 328 329 /* Avoid output sizes that makes the FDC code think it's a single sided 330 floppy. The BIOS always report double sided floppies, and even if we 331 the bootsector adjust it's bMaxHeads value when getting a 20h error 332 we end up with a garbaged image (seems somewhere in the BIOS/FDC it is 333 still treated as a double sided floppy and we get half the data we want 334 and with gaps). 335 336 Similarly, if the size is 320KB or 360KB the FDC detects it as a double 337 sided 5.25" floppy with 40 tracks, while the BIOS keeps reporting a 338 1.44MB 3.5" floppy. So, just avoid those sizes too. */ 463 PBS3BOOTSECTOR pBs = (PBS3BOOTSECTOR)paInputs[0].pvBits; 464 if ( memcmp(pBs->abLabel, RT_STR_TUPLE(BS3_LABEL)) == 0 465 && memcmp(pBs->abFSType, RT_STR_TUPLE(BS3_FSTYPE)) == 0 466 && memcmp(pBs->abOemId, RT_STR_TUPLE(BS3_OEMID)) == 0) 467 pBs->cLargeTotalSectors = (paInputs[0].cbBits + paInputs[1].cbBits) / 512; 468 else 469 return RTMsgErrorExitFailure("Didn't find magic strings in the first file (%s).", paInputs[0].pszFile); 470 471 /* 472 * Write out the image. 473 */ 474 for (unsigned i = 0; i < cInputs; i++) 475 { 476 Assert(ftell(pOutput) == (int32_t)paInputs[i].offInImage); 477 ssize_t cbWritten = fwrite(paInputs[i].pvBits, sizeof(uint8_t), paInputs[i].cbBits, pOutput); 478 if (cbWritten != (ssize_t)paInputs[i].cbBits) 479 return RTMsgErrorExitFailure("fwrite failed (%zd vs %zu)", cbWritten, paInputs[i].cbBits); 480 } 481 482 /* 483 * Avoid output sizes that makes the FDC code think it's a single sided 484 * floppy. The BIOS always report double sided floppies, and even if we 485 * the bootsector adjust it's bMaxHeads value when getting a 20h error 486 * we end up with a garbaged image (seems somewhere in the BIOS/FDC it is 487 * still treated as a double sided floppy and we get half the data we want 488 * and with gaps). 489 * 490 * Similarly, if the size is 320KB or 360KB the FDC detects it as a double 491 * sided 5.25" floppy with 40 tracks, while the BIOS keeps reporting a 492 * 1.44MB 3.5" floppy. So, just avoid those sizes too. 493 */ 339 494 uint32_t cbOutput = ftell(pOutput); 340 495 if ( cbOutput == 512 * 8 * 40 * 1 /* 160kB 5"1/4 SS */ … … 345 500 static uint8_t const s_abZeroSector[512] = { 0 }; 346 501 if (fwrite(s_abZeroSector, sizeof(uint8_t), sizeof(s_abZeroSector), pOutput) != sizeof(s_abZeroSector)) 502 return RTMsgErrorExitFailure("fwrite failed (padding)"); 503 } 504 505 return RTEXITCODE_SUCCESS; 506 } 507 508 int main(int argc, char **argv) 509 { 510 int rc = RTR3InitExe(argc, &argv, 0); 511 if (RT_FAILURE(rc)) 512 return RTMsgInitFailure(rc); 513 514 /* 515 * Scan the arguments. 516 */ 517 static const RTGETOPTDEF s_aOptions[] = 518 { 519 { "--output", 'o', RTGETOPT_REQ_STRING }, 520 { "--generate-high-dll-import-table", 'g', RTGETOPT_REQ_STRING }, 521 }; 522 523 const char *pszOutput = NULL; 524 const char *pszGenAsmFor = NULL; 525 BS3LNKINPUT aInputs[3]; /* 3 = bootsector, low image, high image */ 526 unsigned cInputs = 0; 527 uint32_t cSectors = 0; 528 529 RTGETOPTSTATE GetState; 530 rc = RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, RTGETOPTINIT_FLAGS_OPTS_FIRST); 531 AssertRCReturn(rc, RTEXITCODE_SYNTAX); 532 RTGETOPTUNION ValueUnion; 533 int ch; 534 while ((ch = RTGetOpt(&GetState, &ValueUnion))) 535 { 536 switch (ch) 347 537 { 348 fprintf(stderr, "error: fwrite failed (padding)\n"); 349 rcExit = 1; 538 case 'o': 539 if (pszOutput) 540 return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Only one output file is allowed. You've specified '%s' and '%s'", 541 pszOutput, ValueUnion.psz); 542 pszOutput = ValueUnion.psz; 543 break; 544 545 case 'g': 546 if (pszGenAsmFor) 547 return RTMsgErrorExit(RTEXITCODE_SYNTAX, "--generate-high-dll-import-table can only be used once (first for %s, now for %s)", 548 pszGenAsmFor, ValueUnion.psz); 549 pszGenAsmFor = ValueUnion.psz; 550 break; 551 552 case VINF_GETOPT_NOT_OPTION: 553 { 554 if (pszGenAsmFor) 555 return RTMsgErrorExit(RTEXITCODE_SYNTAX, "--generate-high-dll-import-table don't take any non-option arguments!"); 556 557 /* 558 * Add to input file collection. 559 */ 560 if (cInputs >= RT_ELEMENTS(aInputs)) 561 return RTMsgErrorExitFailure("Too many input files!"); 562 aInputs[cInputs].pszFile = ValueUnion.psz; 563 #if defined(RT_OS_OS2) || defined(RT_OS_WINDOWS) 564 FILE *pFile = fopen(aInputs[cInputs].pszFile, "rb"); 565 #else 566 FILE *pFile = fopen(aInputs[cInputs].pszFile, "r"); 567 #endif 568 if (pFile) 569 { 570 if (fseek(pFile, 0, SEEK_END) == 0) 571 { 572 aInputs[cInputs].cbFile = (uint32_t)ftell(pFile); 573 if (fseek(pFile, 0, SEEK_SET) == 0) 574 { 575 if (cInputs != 0 || aInputs[cInputs].cbFile == 512) 576 { 577 cSectors += RT_ALIGN_32(aInputs[cInputs].cbFile, 512) / 512; 578 if (cSectors <= BS3_MAX_SIZE / 512 || cInputs > 0) 579 { 580 if (cSectors > 0) 581 { 582 aInputs[cInputs].pvBits = NULL; 583 aInputs[cInputs].cbBits = 0; 584 aInputs[cInputs].hLdrMod = NIL_RTLDRMOD; 585 aInputs[cInputs++].pFile = pFile; 586 pFile = NULL; 587 break; 588 } 589 RTMsgError("empty input file: '%s'", aInputs[cInputs].pszFile); 590 } 591 else 592 RTMsgError("input is too big: %u bytes, %u sectors (max %u bytes, %u sectors)\n" 593 "detected loading '%s'", 594 cSectors * 512, cSectors, BS3_MAX_SIZE, BS3_MAX_SIZE / 512, 595 aInputs[cInputs].pszFile); 596 } 597 else 598 RTMsgError("first input file (%s) must be exactly 512 bytes", aInputs[cInputs].pszFile); 599 } 600 else 601 RTMsgError("seeking to start of '%s' failed", aInputs[cInputs].pszFile); 602 } 603 else 604 RTMsgError("seeking to end of '%s' failed", aInputs[cInputs].pszFile); 605 } 606 else 607 RTMsgError("Failed to open input file '%s' for reading", aInputs[cInputs].pszFile); 608 if (pFile) 609 fclose(pFile); 610 return RTEXITCODE_FAILURE; 611 } 612 613 case 'V': 614 printf("%s\n", "$Revision$"); 615 return RTEXITCODE_SUCCESS; 616 617 case 'h': 618 printf("usage: %s --output <output> <basemod> [high-dll1... [high-dllN]]\n" 619 " or: %s --output <high-dll.asm> --generate-high-dll-import-table <some.high-dll>\n" 620 " or: %s --help\n" 621 " or: %s --version\n" 622 , argv[0], argv[0], argv[0], argv[0]); 623 return RTEXITCODE_SUCCESS; 624 625 default: 626 return RTGetOptPrintError(ch, &ValueUnion); 350 627 } 351 628 } 629 630 if (!pszOutput) 631 return RTMsgErrorExit(RTEXITCODE_SYNTAX, "No output file was specified (-o or --output)."); 632 633 if (cInputs == 0 && !pszGenAsmFor) 634 return RTMsgErrorExit(RTEXITCODE_SYNTAX, "No input files was specified."); 635 636 /* 637 * Do the job. 638 */ 639 /* Open the output file */ 640 #if defined(RT_OS_OS2) || defined(RT_OS_WINDOWS) 641 FILE *pOutput = fopen(pszOutput, !pszGenAsmFor ? "wb" : "w"); 642 #else 643 FILE *pOutput = fopen(pszOutput, "w"); 644 #endif 645 if (!pOutput) 646 RTMsgErrorExitFailure("Failed to open output file '%s' for writing!", pszOutput); 647 648 RTEXITCODE rcExit; 649 if (pszGenAsmFor) 650 rcExit = GenerateHighDllImportTableAssembly(pOutput, pszGenAsmFor); 651 else 652 rcExit = DoTheLinking(pOutput, aInputs, cInputs); 352 653 353 654 /* Finally, close the output file (can fail because of buffered data). */ 354 655 if (fclose(pOutput) != 0) 355 { 356 fprintf(stderr, "error: Error closing '%s'.\n", pszOutput); 357 rcExit = 1; 358 } 359 656 rcExit = RTMsgErrorExitFailure("Error closing '%s'!", pszOutput); 657 658 /* Delete the output file on failure. */ 659 if (rcExit != RTEXITCODE_SUCCESS) 660 RTFileDelete(pszOutput); 661 662 /* Close the input files and free memory associated with them. */ 663 for (unsigned i = 0; i < cInputs && rcExit == 0; i++) 664 { 665 if (aInputs[i].pFile) 666 fclose(aInputs[i].pFile); 667 if (aInputs[i].hLdrMod != NIL_RTLDRMOD) 668 RTLdrClose(aInputs[i].hLdrMod); 669 if (aInputs[i].pvBits) 670 RTMemFree(aInputs[i].pvBits); 671 } 672 673 /* Close stderr to make sure it's flushed properly. */ 360 674 fclose(stderr); 361 675 return rcExit; -
trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-SlabAllocFixed.c
r102144 r102157 43 43 44 44 45 #undef Bs3SlabAlloc Ex46 BS3_CMN_DEF( void BS3_FAR *, Bs3SlabAllocEx,(PBS3SLABCTL pSlabCtl, uint16_t cChunks, uint16_t fFlags))45 #undef Bs3SlabAllocFixed 46 BS3_CMN_DEF(uint16_t, Bs3SlabAllocFixed,(PBS3SLABCTL pSlabCtl, uint32_t uFlatAddr, uint16_t cChunks)) 47 47 { 48 BS3_ASSERT(cChunks > 0);49 if ( pSlabCtl->cFreeChunks >=cChunks)48 uint32_t iBit32 = (uFlatAddr - BS3_XPTR_GET_FLAT(void, pSlabCtl->pbStart)) >> pSlabCtl->cChunkShift; 49 if (iBit32 < pSlabCtl->cChunks) 50 50 { 51 int32_t iBit = ASMBitFirstClear(&pSlabCtl->bmAllocated, pSlabCtl->cChunks); 52 if (iBit >= 0) 53 { 54 BS3_ASSERT(!ASMBitTest(&pSlabCtl->bmAllocated, iBit)); 51 uint16_t iBit = (uint16_t)iBit32; 52 uint16_t i; 55 53 56 while ((uint32_t)iBit + cChunks <= pSlabCtl->cChunks) 57 { 58 /* Check that we've got the requested number of free chunks here. */ 59 uint16_t i; 60 for (i = 1; i < cChunks; i++) 61 if (ASMBitTest(&pSlabCtl->bmAllocated, iBit + i)) 62 break; 63 if (i == cChunks) 64 { 65 /* Check if the chunks are all in the same tiled segment. */ 66 BS3_XPTR_AUTO(void, pvRet); 67 BS3_XPTR_SET_FLAT(void, pvRet, 68 BS3_XPTR_GET_FLAT(uint8_t, pSlabCtl->pbStart) + ((uint32_t)iBit << pSlabCtl->cChunkShift)); 69 if ( !(fFlags & BS3_SLAB_ALLOC_F_SAME_TILE) 70 || (BS3_XPTR_GET_FLAT(void, pvRet) >> 16) 71 == ((BS3_XPTR_GET_FLAT(void, pvRet) + ((uint32_t)cChunks << pSlabCtl->cChunkShift) - 1) >> 16) ) 72 { 73 /* Complete the allocation. */ 74 void *fpRet; 75 for (i = 0; i < cChunks; i++) 76 ASMBitSet(&pSlabCtl->bmAllocated, iBit + i); 77 pSlabCtl->cFreeChunks -= cChunks; 78 fpRet = BS3_XPTR_GET(void, pvRet); 79 #if ARCH_BITS == 16 80 BS3_ASSERT(fpRet != NULL); 81 #endif 82 return fpRet; 83 } 54 /* If the slab doesn't cover the entire area requested, reduce it. 55 Caller can then move on to the next slab in the list to get the rest. */ 56 if (pSlabCtl->cChunks - iBit < cChunks) 57 cChunks = pSlabCtl->cChunks - iBit; 84 58 85 /* 86 * We're crossing a tiled segment boundrary. 87 * Skip to the start of the next segment and retry there. 88 * (We already know that the first chunk in the next tiled 89 * segment is free, otherwise we wouldn't have a crossing.) 90 */ 91 BS3_ASSERT(((uint32_t)cChunks << pSlabCtl->cChunkShift) <= _64K); 92 i = BS3_XPTR_GET_FLAT_LOW(void, pvRet); 93 i = UINT16_C(0) - i; 94 i >>= pSlabCtl->cChunkShift; 95 iBit += i; 96 } 97 else 98 { 99 /* 100 * Continue searching. 101 */ 102 iBit = ASMBitNextClear(&pSlabCtl->bmAllocated, pSlabCtl->cChunks, iBit + i); 103 if (iBit < 0) 104 break; 105 } 106 } 107 } 59 /* Check that all the chunks are free. */ 60 for (i = 0; i < cChunks; i++) 61 if (ASMBitTest(&pSlabCtl->bmAllocated, iBit + i)) 62 return UINT16_MAX; 63 64 /* Complete the allocation. */ 65 for (i = 0; i < cChunks; i++) 66 ASMBitSet(&pSlabCtl->bmAllocated, iBit + i); 67 pSlabCtl->cFreeChunks -= cChunks; 68 return cChunks; 108 69 } 109 return NULL;70 return 0; 110 71 } 111 72 -
trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-first-common.mac
r102131 r102157 52 52 ; 53 53 54 ; 55 ; 16-bit text 54 55 ; 0x86a00 56 ; 16-bit text 442368 = 0x6C000 (442368) 56 57 ; 57 58 %ifndef BS3_IS_DOS_EXE … … 111 112 BS3_GLOBAL_DATA Bs3Text16_Size, 2 112 113 dw BS3_DATA_NM(Bs3Text16_EndOfSegment) wrt CGROUP16 114 %ifndef BS3_IS_HIGH_IMAGE 113 115 BS3_GLOBAL_DATA Bs3RmText16_Size, 2 114 116 dw BS3_DATA_NM(Bs3RmText16_EndOfSegment) wrt BS3GROUPRMTEXT16 117 %endif ; !BS3_IS_HIGH_IMAGE 115 118 BS3_GLOBAL_DATA Bs3X0Text16_Size, 2 116 119 dw BS3_DATA_NM(Bs3X0Text16_EndOfSegment) wrt BS3GROUPX0TEXT16 … … 118 121 dw BS3_DATA_NM(Bs3X1Text16_EndOfSegment) wrt BS3GROUPX1TEXT16 119 122 123 %ifndef BS3_IS_HIGH_IMAGE 120 124 BS3_GLOBAL_DATA Bs3RmText16_FlatAddr, 4 121 125 dd BS3_DATA_NM(Bs3RmText16_StartOfSegment) wrt BS3FLAT 126 %endif ; !BS3_IS_HIGH_IMAGE 122 127 BS3_GLOBAL_DATA Bs3X0Text16_FlatAddr, 4 123 128 dd BS3_DATA_NM(Bs3X0Text16_StartOfSegment) wrt BS3FLAT … … 164 169 %endif 165 170 171 %ifndef BS3_IS_HIGH_IMAGE 166 172 ; 167 173 ; 16-bit real-mode text … … 174 180 BS3_GLOBAL_DATA Bs3RmText16_EndOfSegment, 0 175 181 GROUP BS3GROUPRMTEXT16 BS3RMTEXT16_START BS3RMTEXT16 BS3RMTEXT16_END 176 182 %endif ; !BS3_IS_HIGH_IMAGE 177 183 178 184 ; … … 199 205 GROUP BS3GROUPX1TEXT16 BS3X1TEXT16_START BS3X1TEXT16 BS3X1TEXT16_END 200 206 207 %ifndef BS3_IS_HIGH_IMAGE 201 208 ; 202 209 ; Separate the BS3X1TEXT16_END from BS3_BEGIN_TEXT32 to better help pinpoint … … 208 215 BS3_GLOBAL_DATA BS3SEPARATE16AND32BITCODE_EndOfSegment, 0 209 216 GROUP BS3SEPARATE16AND32BITCODEGROUP BS3SEPARATE16AND32BITCODE 217 %endif ; !BS3_IS_HIGH_IMAGE 210 218 211 219 … … 220 228 221 229 230 %ifndef BS3_IS_HIGH_IMAGE 222 231 ; 223 232 ; This is a hack to separate the 32-bit and 64-bit text segments when linking, … … 230 239 BS3_GLOBAL_DATA Bs3Separate32And64BitCode_EndOfSegment, 0 231 240 GROUP BS3SEPARATE32AND64BITCODEGROUP BS3SEPARATE32AND64BITCODE 241 %endif ; !BS3_IS_HIGH_IMAGE 232 242 233 243 … … 276 286 277 287 288 %ifndef BS3_IS_HIGH_IMAGE 289 ; 290 ; The high dll table segment. 291 ; 292 section BS3HIGHDLLEXPORTS align=4 CLASS=BS3HIGHDLLCLASS PUBLIC USE32 FLAT ;; @todo Consider moving this to DATA16... 293 section BS3HIGHDLLIMPORTS align=4 CLASS=BS3HIGHDLLCLASS PUBLIC USE32 FLAT 294 section BS3HIGHDLLSTRINGS align=4 CLASS=BS3HIGHDLLCLASS PUBLIC USE32 FLAT 295 section BS3HIGHDLLTABLE align=4 CLASS=BS3HIGHDLLCLASS PUBLIC USE32 FLAT 296 BS3_GLOBAL_DATA g_aBs3HighDllTable, 0 297 section BS3HIGHDLLTABLE_END align=4 CLASS=BS3HIGHDLLCLASS PUBLIC USE32 FLAT 298 BS3_GLOBAL_DATA g_Bs3HighDllTable_End, 0 299 GROUP BS3HIGHDLLGROUP BS3HIGHDLLIMPORTS BS3HIGHDLLEXPORTS BS3HIGHDLLSTRINGS BS3HIGHDLLTABLE BS3HIGHDLLTABLE_END 300 278 301 ; 279 302 ; 16-bit accessible system data. … … 288 311 BS3_BEGIN_TEXT16 289 312 BS3_GLOBAL_NAME_EX Bs3KitEntryPoint, function, 0 290 313 %endif ; !BS3_IS_HIGH_IMAGE 314 -
trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-BiosInt15hE820.asm
r98103 r102157 172 172 jc .failed 173 173 cmp eax, INT15_E820_SIGNATURE 174 j c.failed174 jne .failed 175 175 cmp ecx, 20 176 176 jb .failed -
trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-DiskQueryGeometry.asm
r102150 r102157 1 1 ; $Id$ 2 2 ;; @file 3 ; BS3Kit - Bs3 BiosInt15hE8203 ; BS3Kit - Bs3DiskQueryGeometry 4 4 ; 5 5 … … 39 39 ;********************************************************************************************************************************* 40 40 %include "bs3kit-template-header.mac" 41 42 43 ;*********************************************************************************************************************************44 ;* Defined Constants And Macros *45 ;*********************************************************************************************************************************46 ;; Signature: 'SMAP'47 %define INT15_E820_SIGNATURE 0534d4150h48 41 49 42 … … 118 111 BS3_SET_BITS 16 119 112 %endif 120 ; Ralf Brown suggest setting es:di to NULL before the call. This is also helpful 121 ; wrt to IVT manipulation (next step). 113 114 ; 115 ; Ralf Brown suggest setting es:di to NULL before the call. 116 ; Doubt this is really needed in our case, but whatever. 117 ; 122 118 xor di, di 123 119 mov es, di 124 125 ;126 ; Save current and restore the original IVT[13h] entry.127 ;128 mov si, seg g_aBs3RmIvtOriginal129 mov ds, si130 mov si, g_aBs3RmIvtOriginal131 132 push word [es:13h * 4]133 mov ax, [si + 13h * 4]134 mov [es:13h * 4], ax135 136 push word [es:13h * 4 + 2]137 mov ax, [si + 13h * 4 + 2]138 mov [es:13h * 4 + 2], ax139 120 140 121 ; … … 145 126 mov es, di 146 127 int 13h 147 148 ;149 ; Restore the modified IVT[13h] entry.150 ; Must not touch EFLAGS.CF!151 ;152 push word 0153 pop ds154 pop word [ds:13h * 4 + 2]155 pop word [ds:13h * 4]156 128 157 129 ; -
trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-DiskRead.asm
r102150 r102157 1 1 ; $Id$ 2 2 ;; @file 3 ; BS3Kit - Bs3 BiosInt15hE8203 ; BS3Kit - Bs3DiskRead 4 4 ; 5 5 … … 42 42 43 43 ;********************************************************************************************************************************* 44 ;* Defined Constants And Macros *45 ;*********************************************************************************************************************************46 ;; Signature: 'SMAP'47 %define INT15_E820_SIGNATURE 0534d4150h48 49 50 ;*********************************************************************************************************************************51 44 ;* External symbols * 52 45 ;********************************************************************************************************************************* … … 55 48 BS3_BEGIN_TEXT16 56 49 extern RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_Safe_rm) 57 BS3_EXTERN_DATA16 g_aBs3RmIvtOriginal 50 51 BS3_EXTERN_DATA16 g_aBs3RmIvtOriginal 52 %ifdef TMPL_16BIT 53 BS3_EXTERN_CMN Bs3SelProtFar16DataToRealMode 54 %else 55 BS3_EXTERN_CMN Bs3SelFlatDataToRealMode 56 %endif 57 58 58 59 59 60 60 ;; 61 ; Performs a int 13h function 8call.62 ; 63 ; @cproto BS3_MODE_PROTO_STUB(uint8_t, Bs3Disk QueryGeometry,(uint8_t bDrive, uint16_t *puMaxCylinder,64 ; uint8_t *puMaxHead, uint8_t *puMaxSector));61 ; Performs a int 13h function 2 call. 62 ; 63 ; @cproto BS3_MODE_PROTO_STUB(uint8_t, Bs3DiskRead,(uint8_t bDrive, uint16_t uCylinder, uint8_t uHead, uint8_t uSector, 64 ; uint8_t cSectors, void RT_FAR *pvBuf)); 65 65 ; 66 66 ; @returns Register value (ax/eax). Zero on success, non-zero on failure. … … 72 72 ; 73 73 TMPL_BEGIN_TEXT 74 BS3_PROC_BEGIN_MODE Bs3Disk QueryGeometry, BS3_PBC_HYBRID74 BS3_PROC_BEGIN_MODE Bs3DiskRead, BS3_PBC_HYBRID 75 75 push xBP 76 76 mov xBP, xSP … … 90 90 ; Load/Save parameters. 91 91 %define a_bDrive [xBP + xCB + cbCurRetAddr + xCB*0] 92 %define a_puMaxCylinder [xBP + xCB + cbCurRetAddr + xCB + sCB*0] 93 %define a_pMaxHead [xBP + xCB + cbCurRetAddr + xCB + sCB*1] 94 %define a_puMaxSector [xBP + xCB + cbCurRetAddr + xCB + sCB*2] 92 %define a_uCylinder [xBP + xCB + cbCurRetAddr + xCB*1] 93 %define a_uCylinderHi [xBP + xCB + cbCurRetAddr + xCB*1 + 1] 94 %define a_uHead [xBP + xCB + cbCurRetAddr + xCB*2] 95 %define a_uSector [xBP + xCB + cbCurRetAddr + xCB*3] 96 %define a_cSectors [xBP + xCB + cbCurRetAddr + xCB*4] 97 %define a_pvBuf [xBP + xCB + cbCurRetAddr + xCB*5] 98 %define a_pvBufSel [xBP + xCB + cbCurRetAddr + xCB*5 + 2] 95 99 96 100 %ifdef TMPL_64BIT 97 101 mov a_bDrive, rcx ; save bDrive 98 mov a_ puMaxCylinder, rdx ; save pcCylinders99 mov a_ pMaxHead, r8 ; save pcHeads100 mov a_ puMaxSector, r9 ; save pcSectors102 mov a_uCylinder, rdx ; save uCylinder 103 mov a_uHead, r8 ; save uHead 104 mov a_uSector, r9 ; save uSector 101 105 movzx edx, cl ; dl = drive 102 106 %else 103 107 mov dl, a_bDrive ; dl = drive 104 108 %endif 109 110 ; 111 ; Convert buffer pointer if not in real mode. 112 ; Note! We clean the stack up in the epilogue. 113 ; 114 %ifdef TMPL_64BIT 115 sub rsp, 20h 116 mov rcx, a_pvBuf 117 call Bs3SelFlatDataToRealMode 118 mov a_pvBuf, rax 119 %elifdef TMPL_32BIT 120 mov ecx, a_pvBuf 121 push ecx 122 call Bs3SelFlatDataToRealMode 123 mov a_pvBuf, eax 124 %elif !BS3_MODE_IS_RM_OR_V86(TMPL_MODE) 125 push word a_pvBufSel 126 push word a_pvBuf 127 call Bs3SelProtFar16DataToRealMode 128 mov a_pvBuf, ax 129 mov a_pvBufSel, dx 130 %endif 131 132 ; 133 ; Set up the BIOS call parameters. 134 ; 135 mov ah, 02h ; read 136 mov al, a_cSectors 137 mov cx, a_uCylinder 138 xchg ch, cl 139 shl cl, 6 140 or cl, a_uSector 141 mov dl, a_bDrive 142 mov dh, a_uHead 143 mov bx, a_pvBuf 144 mov di, a_pvBufSel 105 145 106 146 ; … … 118 158 BS3_SET_BITS 16 119 159 %endif 120 ; Ralf Brown suggest setting es:di to NULL before the call. This is also helpful 121 ; wrt to IVT manipulation (next step). 122 xor di, di 160 161 ; 162 ; Make the call. 163 ; 123 164 mov es, di 124 125 ; 126 ; Save current and restore the original IVT[13h] entry. 127 ; 128 mov si, seg g_aBs3RmIvtOriginal 129 mov ds, si 130 mov si, g_aBs3RmIvtOriginal 131 132 push word [es:13h * 4] 133 mov ax, [si + 13h * 4] 134 mov [es:13h * 4], ax 135 136 push word [es:13h * 4 + 2] 137 mov ax, [si + 13h * 4 + 2] 138 mov [es:13h * 4 + 2], ax 139 140 ; 141 ; Make the call. 142 ; 143 mov ax, 0800h ; ah=08h 144 xor di, di ; ralf brown suggestion to guard against bios bugs. 145 mov es, di 165 ; pushf 166 ; sti 146 167 int 13h 147 148 ; 149 ; Restore the modified IVT[13h] entry. 150 ; Must not touch EFLAGS.CF! 151 ; 152 push word 0 153 pop ds 154 pop word [ds:13h * 4 + 2] 155 pop word [ds:13h * 4] 168 ; popf 156 169 157 170 ; … … 167 180 %endif 168 181 %endif 182 hlt 183 169 184 ; 170 185 ; Check that we didn't failed. 171 186 ; 172 187 jc .failed_return_ah 173 174 ; 175 ; Save the return values. 176 ; CL[7:6]:CH = max cylinders. 177 ; DH = max heads 178 ; CL[5:0] = max sectors 179 ; Other stuff we don't care about: 180 ; AH = 0 181 ; AL = undefined/zero 182 ; BL = drive type 183 ; DL = max drives. 184 ; ES:DI = driver parameter table for floppies. 185 ; 186 %ifdef TMPL_16BIT 187 les di, a_pMaxHead 188 mov [es:di], dh 189 190 les di, a_puMaxSector 191 mov al, 3fh 192 and al, cl 193 mov [es:di], al 194 195 les di, a_puMaxCylinder 196 shr cl, 6 197 xchg cl, ch 198 mov [es:di], cx 199 %else 200 mov xDI, a_pMaxHead 201 mov [xDI], dh 202 203 mov xDI, a_puMaxSector 204 mov al, 3fh 205 and al, cl 206 mov [xDI], al 207 208 mov xDI, a_puMaxCylinder 209 shr cl, 6 210 xchg cl, ch 211 mov [xDI], cx 212 %endif 188 test ah, ah 189 jnz .failed_return_ah 213 190 214 191 ; … … 243 220 dec al 244 221 jmp .return 245 BS3_PROC_END_MODE Bs3Disk QueryGeometry246 222 BS3_PROC_END_MODE Bs3DiskRead 223 -
trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-rm-InitAll.c
r98103 r102157 59 59 Bs3InitGdt_rm_far(); 60 60 61 #ifdef BS3_INIT_ALL_WITH_HIGH_DLLS 62 /* 63 * Load the high DLLs (if any) now, before we bugger up the PIC and 64 * replace the IVT. 65 */ 66 Bs3InitHighDlls_rm_far(); 67 #endif 68 61 69 /* 62 70 * Before we disable all interrupts, try convince the BIOS to stop the -
trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit-autostubs.kmk
r102127 r102157 97 97 $(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3ExtCtxGetFsw) 98 98 $(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3PicUpdateMask) 99 $(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3SlabAllocFixed) 99 100 $(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3SlabFree) 100 101 $(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3TestSubErrorCount) … … 194 195 $(call BS3KIT_FN_GEN_MODE_NEARSTUB,bs3kit-common-16,Bs3SwitchTo32BitAndCallC) 195 196 $(call BS3KIT_FN_GEN_MODE_NEARSTUB,bs3kit-common-16,Bs3BiosInt15h88) 197 $(call BS3KIT_FN_GEN_MODE_NEARSTUB,bs3kit-common-16,Bs3DiskQueryGeometry) 198 $(call BS3KIT_FN_GEN_MODE_NEARSTUB,bs3kit-common-16,Bs3DiskRead) 199 $(call BS3KIT_FN_GEN_MODE_NEARSTUB,bs3kit-common-16,Bs3MemCopyFlat) 196 200 $(call BS3KIT_FN_GEN_MODE_NEARSTUB,bs3kit-common-16,Bs3TrapInit) -
trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit-mangling-code-define.h
r102127 r102157 181 181 #define Bs3SlabAlloc BS3_CMN_MANGLER(Bs3SlabAlloc) 182 182 #define Bs3SlabAllocEx BS3_CMN_MANGLER(Bs3SlabAllocEx) 183 #define Bs3SlabAllocFixed BS3_CMN_MANGLER(Bs3SlabAllocFixed) 183 184 #define Bs3SlabFree BS3_CMN_MANGLER(Bs3SlabFree) 184 185 #define Bs3SlabInit BS3_CMN_MANGLER(Bs3SlabInit) … … 251 252 # define Bs3BiosInt15hE820 BS3_MODE_MANGLER(Bs3BiosInt15hE820) 252 253 # define Bs3CpuDetect BS3_MODE_MANGLER(Bs3CpuDetect) 254 # define Bs3DiskQueryGeometry BS3_MODE_MANGLER(Bs3DiskQueryGeometry) 255 # define Bs3DiskRead BS3_MODE_MANGLER(Bs3DiskRead) 256 # define Bs3MemCopyFlat BS3_MODE_MANGLER(Bs3MemCopyFlat) 253 257 # define Bs3SwitchTo32BitAndCallC BS3_MODE_MANGLER(Bs3SwitchTo32BitAndCallC) 254 258 # define Bs3TestDoModes BS3_MODE_MANGLER(Bs3TestDoModes) -
trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit-mangling-code-undef.h
r102127 r102157 181 181 #undef Bs3SlabAlloc 182 182 #undef Bs3SlabAllocEx 183 #undef Bs3SlabAllocFixed 183 184 #undef Bs3SlabFree 184 185 #undef Bs3SlabInit … … 251 252 # undef Bs3BiosInt15hE820 252 253 # undef Bs3CpuDetect 254 # undef Bs3DiskQueryGeometry 255 # undef Bs3DiskRead 256 # undef Bs3MemCopyFlat 253 257 # undef Bs3SwitchTo32BitAndCallC 254 258 # undef Bs3TestDoModes -
trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit.h
r102127 r102157 615 615 # define BS3_FP_OFF(a_pv) ((uintptr_t)(a_pv)) 616 616 #endif 617 618 /** 619 * Converts a far real mode address to a 32-bit flat address. 620 * 621 * @returns Flat address. 622 * @param a_pv The _real_ _mode_ far pointer to convert. 623 */ 624 #define BS3_FP_REAL_TO_FLAT(a_pv) (((uint32_t)BS3_FP_SEG(a_pv) << 4) + BS3_FP_OFF(a_pv)) 617 625 618 626 /** @def BS3_MAKE_PROT_R0PTR_FROM_FLAT … … 1757 1765 * @param pvSrc The source buffer. 1758 1766 * @param cbToCopy The number of bytes to copy. 1767 * @sa Bs3MemCopyFlat 1759 1768 */ 1760 1769 BS3_CMN_PROTO_STUB(void BS3_FAR *, Bs3MemCpy,(void BS3_FAR *pvDst, const void BS3_FAR *pvSrc, size_t cbToCopy)); … … 2152 2161 2153 2162 /** 2154 * Allocates one or more chunks rom a slab.2163 * Allocates one or more chunks from a slab. 2155 2164 * 2156 2165 * @returns Pointer to the request number of chunks on success, NULL if we're … … 2161 2170 */ 2162 2171 BS3_CMN_PROTO_STUB(void BS3_FAR *, Bs3SlabAllocEx,(PBS3SLABCTL pSlabCtl, uint16_t cChunks, uint16_t fFlags)); 2172 2173 /** 2174 * Allocates a specific range of chunks from a slab. 2175 * 2176 * @returns Number of chunks it was possible to allocate in the slab. 2177 * @retval 0 if the given address isn't in the slab. 2178 * @retval UINT16_MAX if one or more of the requested chunks are already in 2179 * use, so the request cannot be fulfilled. 2180 * @param pSlabCtl The slab control structure to allocate from. 2181 * @param uFlatAddr The flat address of the range to allocate. 2182 * @param cChunks The number of contiguous chunks we want. 2183 */ 2184 BS3_CMN_PROTO_STUB(uint16_t, Bs3SlabAllocFixed,(PBS3SLABCTL pSlabCtl, uint32_t uFlatAddr, uint16_t cChunks)); 2163 2185 2164 2186 /** … … 2542 2564 * Call 16-bit prot mode function from v8086 mode. 2543 2565 * 2544 * This switches from v8086 mode to 16-bit protected mode (code) and execute d2566 * This switches from v8086 mode to 16-bit protected mode (code) and executes 2545 2567 * @a fpfnCall with @a cbParams bytes of parameters pushed on the stack. 2546 2568 * Afterwards it switches back to v8086 mode and returns a 16-bit status code. … … 4131 4153 4132 4154 /** 4155 * Initializes all of boot sector kit \#3 as well as the high DLLs. 4156 */ 4157 BS3_DECL(void) Bs3InitAllWithHighDlls_rm(void); 4158 4159 /** 4133 4160 * Initializes the REAL and TILED memory pools. 4134 4161 * … … 4141 4168 */ 4142 4169 BS3_DECL_FAR(void) Bs3InitGdt_rm_far(void); 4170 4171 /** 4172 * Initializes (loads) any high DLLs. 4173 * 4174 * @note This cannot be called after the PIC or traps have been initialized! 4175 */ 4176 BS3_DECL_FAR(void) Bs3InitHighDlls_rm_far(void); 4143 4177 4144 4178 … … 4337 4371 4338 4372 /** 4373 * Special version of memcpy for copying from/to real mode. 4374 * 4375 * @returns pvDst 4376 * @param uFlatDst The flat address of the destination buffer. 4377 * @param uFlatSrc The flat address of the source buffer. 4378 * @param cbToCopy The number of bytes to copy. Max 64KB. 4379 * 4380 * @todo Only work on 386+ at present. Could be made to work for 286 and 4381 * addresses < 16MB if we care... 4382 */ 4383 BS3_MODE_PROTO_STUB(void BS3_FAR *, Bs3MemCopyFlat,(uint32_t uFlatDst, uint32_t uFlatSrc, uint32_t cbToCopy)); 4384 4385 /** 4339 4386 * Executes the array of tests in every possibly mode. 4340 4387 * … … 4546 4593 /** @} */ 4547 4594 4595 /** @defgroup grp_bs3kit_disk Disk via INT 13h 4596 * @{ 4597 */ 4598 4599 /** 4600 * Performs a int 13h function AL=08h call to get the driver parameters. 4601 * 4602 * @returns 0 on success, non-zero error BIOS code on failure. 4603 * @param bDrive The drive to get parameters for. 4604 * @param puMaxCylinder Where to store the max cylinder value. 4605 * Range: 0 thru *pcMaxCylinder. 4606 * @param puMaxHead Where to store the max head value. 4607 * Range: 0 thru *pcMaxHead. 4608 * @param puMaxSector Where to store the max sector value. 4609 * Range: 1 thru *pcMaxSector. 4610 */ 4611 BS3_MODE_PROTO_STUB(uint8_t, Bs3DiskQueryGeometry,(uint8_t bDrive, uint16_t *puMaxCylinder, 4612 uint8_t *puMaxHead, uint8_t *puMaxSector)); 4613 4614 /** 4615 * Performs a int 13h function AL=08h call to get the driver parameters. 4616 * 4617 * @returns 0 on success, non-zero error BIOS code on failure. 4618 * @param bDrive The drive to read from. 4619 * @param uCylinder The cylinder to start read at (0-max). 4620 * @param uHead The head to start reading at (0-max). 4621 * @param uSector The sector to start reading at (1-max). 4622 * @param cSectors The number of sectors to read (1+). 4623 * @param pvBuf The buffer to read into. This MUST be addressable 4624 * from real mode! 4625 */ 4626 BS3_MODE_PROTO_STUB(uint8_t, Bs3DiskRead,(uint8_t bDrive, uint16_t uCylinder, uint8_t uHead, uint8_t uSector, 4627 uint8_t cSectors, void RT_FAR *pvBuf)); 4628 4629 /** @} */ 4630 4548 4631 4549 4632 /** @} */ -
trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit.mac
r99443 r102157 333 333 ; 334 334 ; !!HACK ALERT!! 335 %ifndef BS3_IS_HIGH_IMAGE 335 336 segment BS3FLAT use32 class=BS3FLAT 336 337 GROUP FLAT BS3FLAT 338 %else 339 ; For HIGH DLLs the hack is WRONG, so we just declare both BS3FLAT and FLAT the way 340 ; wlink wants flat groups to be defined. (See FIX_FRAME_FLAT use in omfreloc.c.) 341 GROUP BS3FLAT 342 GROUP FLAT 343 %endif 337 344 %endif 338 345
Note:
See TracChangeset
for help on using the changeset viewer.