chenall / grub4dos

外部命令和工具源码:https://github.com/chenall/grubutils 下载:
http://grub4dos.chenall.net
GNU General Public License v2.0
651 stars 136 forks source link

XP Install ISO and memory issues on Acer eMachines e725 laptop #154

Closed steve6375 closed 7 years ago

steve6375 commented 7 years ago

Using Easy2Boot (DPMS version) and XP ISO. User reports problems with newer versions of grldr.

Symptom 1: When running DPMS2 batch file after loading XP ISO into memory, it hangs. '.. freezes during green colored message "dpms2: auto-detect...' image

Symptom 2: When booting to XP on hard disk after loading XP ISO into memory, ntldr gives a "Windows NT has found only 0K of low memory. 512k of low memory is required to run Windows NT. You may need to upgrade your computer or run a configuration program provided by the manufacturer." message and will not boot.

This occurs on emachines Acer e725 (3 GB RAM, 2.4 GHz x64 processor dual core), intel chipset. I have also had one other user report very similar symptoms with acer aspire one d255.

0.4.5c 18 05 2015 OK

grldr 0.4.6a versions: 23/12/2016 OK 04/02/2017 FAIL 15/05/2017 FAIL 10/06/2017 FAIL 11/06/2017 FAIL 18/06/2017 FAIL

For grub4dos code for Symptom 2 - see Easy2Boot "_ISO\e2b\grub\XPStep2.g4b" And use on an installed XP HDD. Good grldr will boot to XP, bad grldr will give '0K of low memory' error.

!BAT
insmod /%grub%/getstr.g4b

errorcheck off
#remove animated icon fd3 (and fd2)
map --unmap=3 > nul
map --unmap=2 > nul
map --rehook > nul

# pick an ISO
getstr.g4b $$STRbx21
echo -e %STR%

#echo XP INSTALL - STEP 2
#echo ===================
echo
if not "%XPISO%"=="" set ISO=%XPISO% && goto :skpxpi
# list all files in the folder so the user can pick one
/%grub%/PickaFile.g4b %MFOLDER% .ISO
echo
# check if user aborted
if "%CHOSEN%"==""  echo Aborting... && /%grub%/configX.g4b (bd)/%grub%/menuWinInstall.lst
set ISO=%CHOSEN%
:skpxpi

# load winvblock anyway!
map --mem (bd)/%grub%/NewWinVBlock.ima.gz (fd0) > nul
map --mem (bd)/%grub%/NewWinVBlock.ima.gz (fd1) > nul

#hd0 is USB
#hd1 is real HDD

map --mem %MFOLDER%/%ISO% (0xff) || map  %MFOLDER%/%ISO% (0xff) > nul

# If user installs to hd2 then we must shift all drives or else ntldr/boot.ini will try to boot to wrong drive
set /a HDCNT=*0x475 & 0xff - 1 > nul
set topmap=(hd%HDCNT%)
clear
if %HDCNT%>=1 map (hd0) %topmap% > nul && map (hd1) (hd0) && echo Mapping (hd0) to %topmap% and (hd1) to (hd0)
if %HDCNT%>=2 map (hd2) (hd1) > nul && if %HDCNT%>=3 map (hd3) (hd2) > nul && if %HDCNT%>=4 map (hd4) (hd3) > nul  && if %HDCNT%>=5 map (hd5) (hd4) > nul && if %HDCNT%>=6 map (hd6) (hd5) > nul && if %HDCNT%>=7 map (hd7) (hd6) > nul && if %HDCNT%>=8 map (hd8) (hd7) > nul

map --hook > nul

map --rd-size=2048 > nul
map --mem (rd)+4 (0x55) > nul
map --rehook > nul
write (0x55) #!GRUB4DOS\x00v=1\x00%MFOLDER%/%ISO%\x00\xA0\x00 > nul
root (hd0,0) > nul || root (hd0,1) > nul || root (hd0,2) > nul || rootnoverify (hd0,0) > nul

chainloader (hd0)+1 > nul

more details to follow.

steve6375 commented 7 years ago

image grldr 0.4.6a 20161224 also FAILS to boot XP

Also this code (which does not use map --mem /ISO) also causes the Symptom 2 issue when booting to XP on a HDD on the eMachines system:

!BAT

errorcheck off
#remove animated icon fd3 (and fd2)
map --unmap=3 > nul
map --unmap=2 > nul
map --rehook > nul

# load getstr batch file into memory
insmod /%grub%/getstr.g4b

getstr.g4b $$STRbLR1
echo -e %STR%
#echo XP INSTALL - STEP 2 LowRAM (only use for Low RAM Systems <512MB)
#echo ===============================================================
echo
if not "%XPISO%"=="" set ISO=%XPISO% && goto :skpxpi
# list all files in the folder so the user can pick one
/%grub%/PickaFile.g4b %MFOLDER% .ISO
echo
# check if user aborted
if "%CHOSEN%"==""  echo Aborting... && /%grub%/configX.g4b (bd)/%grub%/menuWinInstall.lst
set ISO=%CHOSEN%
:skpxpi

debug off
map --mem (bd)/%grub%/NewWinVBlock.ima.gz (fd0) > nul
map --mem (bd)/%grub%/NewWinVBlock.ima.gz (fd1) > nul
map %MFOLDER%/%ISO% (0xff) > nul

set /a HDCNT=*0x475 & 0xff - 1 > nul
set topmap=(hd%HDCNT%)
clear
if %HDCNT%>=1 map (hd0) %topmap% > nul && map (hd1) (hd0) > nul && echo Mapping (hd0) to %topmap% and (hd1) to (hd0)
if %HDCNT%>=2 map (hd2) (hd1) > nul && if %HDCNT%>=3 map (hd3) (hd2) > nul && if %HDCNT%>=4 map (hd4) (hd3) > nul  && if %HDCNT%>=5 map (hd5) (hd4) > nul && if %HDCNT%>=6 map (hd6) (hd5) > nul && if %HDCNT%>=7 map (hd7) (hd6) > nul && if %HDCNT%>=8 map (hd8) (hd7) > nul

map --hook > nul

map --rd-size=2048
map --mem (rd)+4 (0x55)
map --rehook

write (0x55) #!GRUB4DOS\x00v=1\x00%MFOLDER:~1%/%ISO%\x00\xff\x00

root (hd0,0) > nul || root (hd0,1) > nul || root (hd0,2) > nul || rootnoverify (hd0,0) > nul

chainloader (hd0)+1 > nul
steve6375 commented 7 years ago

The user has confirmed that if above code is used but you comment out the following lines so that they do not execute

#map --rd-size=2048
#map --mem (rd)+4 (0x55)
#map --rehook

#write (0x55) #!GRUB4DOS\x00v=1\x00%MFOLDER:~1%/%ISO%\x00\xff\x00

Then XP can be booted without error.

So the 0K message is caused by this code but only on certain systems.

yaya2007 commented 7 years ago

Have a try

steve6375 commented 7 years ago

That version does not work even on a virtual machine or 'good' system which was OK before. So it is buggy.

image

yaya2007 commented 7 years ago

After map --rd-size=2048 map --mem (rd)+4 (0x55) map --rehook

insert map --status

and see feedback.

steve6375 commented 7 years ago

It does not get that far in the code! It is now failing on map --mem (bd)/%grub%/NewWinVBlock.ima.gz (fd0) > nul which is before the map --mem (rd) lines

yaya2007 commented 7 years ago

insert map --status pause

steve6375 commented 7 years ago

not working FAIL grldr 2017 Screenshot of map --status before and after map --mem (rd) - SYMPTOM 0k memory on XP boot

working OK grldr 2016-12-23 Screenshot of map --status before and after map --mem (rd) - XP Boot OK (old grub4dos)

yaya2007 commented 7 years ago

"Dpms2: auto-detect...". Which one is it?

steve6375 commented 7 years ago

I don't understand the question? DPMS2 auto-detect is Symptom #1 and I have not done any experiments with it to find where problem is. Easy2Boot - Install Windows - 0 Install XP - Step 1 [Alt+1]

Symptom 2 is 0K memory issue which you get with Easy2Boot - Install Windows - 2 XP install - step 2 for Low RAM [Alt+3]

yaya2007 commented 7 years ago

screenshot :Which one is wrong?

steve6375 commented 7 years ago

First screenshot shows FAIL for Symptom #2 with grub4dos 0.4.6a 2017 2nd screenshot show PASS for symptom #2 with grub4dos 0.4.6a 23/12/2016

yaya2007 commented 7 years ago

First screenshot shows FAIL for Symptom #2 with grub4dos 0.4.6a 2017 =Screenshot of map --status before and after map --mem (rd) - SYMPTOM 0k memory on XP boot?

2nd screenshot show PASS for symptom #2 with grub4dos 0.4.6a 23/12/2016 =Screenshot of map --status before and after map --mem (rd) - XP Boot OK (old grub4dos)

steve6375 commented 7 years ago

yes

steve6375 commented 7 years ago

It looks like (rd) is using exact area of memory at 0xBBAFF000 length 0x1000 ????

For some reason this is causing a problem (maybe bad BIOS memory map)?

Suggest you do not use any area of memory which is smaller than say 4MB in memory map (i.e. ignore any usable RAM <4MB in size) ???

yaya2007 commented 7 years ago

The role of 0x55 memory disks is not cleared ?8 sector is not enough, follow-up to expand?

steve6375 commented 7 years ago
map --rd-size=2048
map --mem (rd)+4 (0x55)
map --rehook

write (0x55) #!GRUB4DOS\x00v=1\x00%MFOLDER:~1%/%ISO%\x00\xff\x00

Why 8 sectors when 4 have been specified? (rd)+4 = 4 sectors = 2048 bytes is 8 sectors minimum for (rd) ??? Works OK with grldr 2016-12-23 version - so only problem is which memory address is used. Memory is used to hold firadisk instruction.

It is dangerous to use small areas of usable memory in the BIOS memory map. Windows does not use small areas of memory. So if memory map is wrong then it may mean grub4dos will fail but linux\windows OS is OK. So suggest you do not use small areas of memory in memory map.

yaya2007 commented 7 years ago

ignore any usable RAM <4MB in size grldr.rar.txt

steve6375 commented 7 years ago

User reports new version works OK :-)

yaya2007 commented 7 years ago

This is a special case, not the best one. Test respectively :

  1. map --mem (rd)+0x20 (0x55)
  2. map --mem (rd)+0x200 (0x55)
  3. map --mem (rd)+0x700 (0x55)
steve6375 commented 7 years ago
map --rd-size=2048
map --mem (rd)+4 (0x55)

For Symptom 1 (DPMS2 hang), The above code is not used. Therefore I cannot change the map --mem (rd)+4 command because it is not present.

The only (rd) commands in Symptom 1 code are

;; fill (rd) with 0's , 0x82d0 is rd-base mem address, Fn24 is memset - fill memory  <addr> <string> <size>
call Fn.24  0x60000 0x20  102400 > nul ;; map (md)0x300+200 (rd) > nul
if exist ()/_ISO/e2b/firadisk/RUNXP.cmd dd if=(rd)+1 of=()/_ISO/e2b/firadisk/RUNXP.cmd > nul

Also DPMS2.g4b contains:

map --mem (md)+5760 (8)
map --hook

I am not sure what is causing the problem for Symptom 1.

I need to ask the user to test every time (I cannot test because I do not have the system!).

I think the <4M exclusion is a good workaround. I cannot see it causing a problem and the user has confirmed that it does work for both symptom 1 and symptom 2. Also, 0.4.5c works OK. Therefore the problem is with the new feature of grub4dos using top memory. It is wise to avoid small unused areas of memory. It is also wise to not use the highest (top) 2MB of memory because of BIOS bugs which report a memory map incorrectly. In my experience it is common for the BIOS to report the last MB or so of RAM as 'usable RAM' when in fact it is used by the BIOS as a scratchpad area and if you try to use it under DOS it can cause problems. So I never use very top of memory in my code.

So, in summary, I think the <4MB fix is a good workaround and safe to implement.

yaya2007 commented 7 years ago

Usable RAM: Serial number Base Length
1 0 0x9E000 2 0x100000 0xBB86C000 3 0xBB9BF000 0xC3000 4 0xBBABF000 0x2D000 5 0xBBAFF000 0x1000

The problem is that (0x55) is located in serial number 5. The new version moves (0x55) from serial number 5 to serial number 2. How about moving to serial number 3? How about moving to serial number 4?

yaya2007 commented 7 years ago

hypothesis: Usable RAM: Serial number Base Length 1 0 0x9E000 2 0x100000 0xBB86C000 3 0xBB9BF000 0xC3000 4 0xBBABF000 0x2D000 5 0xBBAFF000 0x411000

Will the new version be successful? Now (0x55) is located at serial number 5!

yaya2007 commented 7 years ago

You don't have to test. I have verified that boot 0PE can only use memory blocks of serial number 2

nijazxp commented 7 years ago

OK, idk what're you talking about, but these don't work: map --mem (rd)+0x20 (0x55) map --mem (rd)+0x200 (0x55) map --mem (rd)+0x700 (0x55) Tell me if you need anymore tests.

yaya2007 commented 7 years ago

Thank you. map --mem (RD) +0x700 (0x55), should work.Fail unexpectedly!

nijazxp commented 7 years ago

What do you mean? Don't understand you (fail unexpectedly?) !

yaya2007 commented 7 years ago

map --rd-size=2048 map --mem (rd)+0x700 (0x55) map --rehook

Should succeed .

nijazxp commented 7 years ago

Sorry, doesn't work. First time you said that, it said error 11 unrecognized string. Second time you said it, 0k error. Probably typo.

yaya2007 commented 7 years ago

Well, let me think about it Tell you when you need it

steve6375 commented 7 years ago

To avoid using the top of the lower memory block, please could you try

map --rd-size=0x1100 map --mem (rd)+0x1100 (0x55) map --rehook

steve6375 commented 7 years ago

@yaya2007 The XP error message says '512k of low memory is required to run Windows NT' This implies that it has a problem with the size of lower memory returned by a BIOS call (maybe Int 15h AH=E820 or AH=E801 or AH=88 ??? i.e. memory below 1MB?? Presumably the grub4dos code is adjusting the Int 15 BIOS values returned for free memory? Perhaps there is a problem with this code (maybe it is relying on some registers being preserved by the BIOS when they are not preserved?). I wrote an article on the problems with E801 http://www.rmprepusb.com/tutorials/biostestmem

steve6375 commented 7 years ago

I have reproduced the 0K issue on my Lenovo IdeaPad 300 notebook! I used a HDD which already had XP installed on it. It gave 0K error (when used older 2016-12-23 version it starts to boot OK)

Here are some results rd-size=2048 (rd)+4 = (default case) Start_Sector=43FFF0 Sector_count=8 0K error FAIL rd-size=2048 (rd)+0x700 = Start_sector=43FFF0 Sector_count=8 0K error FAIL rd-size=2048 (rd)+0x2000 = Start_sector=43FFF0 Sector_count=8 0K error FAIL rd-size=0x2000 (rd)+4 = Start_sector=43FFF0 Sector_count=8 0K error FAIL rd-size=2048 (rd)+0x1100 = Start_sector=43FFF0 Sector_count=8 0K error FAIL rd-size=0x1000 (rd)+0x1000 = Start_sector=43FFF0 Sector_count=8 0K error FAIL rd-size=4096 (rd)+4096 = Start_sector=43FFF0 Sector_count=8 0K error FAIL rd-size=0x2000 (rd)+0x2000 = Start_sector=4295E0 Sector_count=10 PASS (boots) rd-size=0x1800 (rd)+0x1800 = Start_sector=4295E0 Sector_count=10 PASS (boots) rd-size=0x1400 (rd)+0x1400 = Start_sector=4295E0 Sector_count=10 PASS (boots) rd-size=0x1100 (rd)+0x1100 = Start_sector=4295E0 Sector_count=10 PASS (boots) rd-size=4097 (rd)+4097 = Start_sector=42AB20 Sector_count=10 PASS (boots)

IdeaPad 300 displaymem

Usable    Length
0             9E800
100000      73B9D000
73CC8000  B1000
74679000  10F15000
87FFE000   1000         = 43FFF0 start sector ***
100000000 17286000

Note 1000 area is used - same problem as other systems!

steve6375 commented 7 years ago

I checked BIOS int 15h AX=E801 and AX=8800 and they return 3C00 and FFFF always. So that is not the problem.

steve6375 commented 7 years ago

Here is simplified code - boot from USB drive on an XP system >> 0K Error

title TEST XP BUG
if not exist RDS set RDS=2048
if not exist RD set RD=4
displaymem
map --rd-size=%RDS%
map --mem (rd)+%RD% (0x55)
map --rehook
echo
echo --rd-size=%RDS%  (rd)+%RD%
echo
map --status
pause

map (hd1) (hd0)
map (hd0) (hd1)
map --hook
root (hd0,0) > nul
chainloader (hd0,0)/ntldr
boot

0.4.6a 2016-12-23 OK - boots to XP 0.4.6a 2017-xx xx FAIL 0K memory error

nijazxp commented 7 years ago

1000 doesnt work

steve6375 commented 7 years ago

0x1100 should work

nijazxp commented 7 years ago

Nothing works now that i copied all that 3 lines. When I copied only one line it gave 0k error. Now nothing. cam00001_crop

and when I press any key and again that step cam00002_crop

steve6375 commented 7 years ago

map --rd-size=0x1100 map --mem (rd)+0x1100 (0x55) map --rehook

Sorry, I made a typo!

nijazxp commented 7 years ago

works

yaya2007 commented 7 years ago

Usable Length 0 9E800 100000 73B9D000 73CC8000 B1000 74679000 10F15000 = 4295E0 start sector, PASS (boots) 87FFE000 1000 = 43FFF0 start sector, 0K error FAIL 100000000 17286000

Does that make sense: As long as (0x55) is not in the last block of 4Gb memory, can succeed .

steve6375 commented 7 years ago

As far as I can tell, it is the map command that is causing the problem. The area of memory is cleared with 0x20 bytes when the map command is executed, but even if I restore the contents (which contained 'mmap' 4kcontents text and some x86 code instructions before), then I still get the NTLDR 0K error.

I tried the code below which clears the 4K area and it still boots to XP OK (pass)

title TEST XP BUG #2
cat --hex (md)0x43FFF0+1 && pause
dd of=(md)0x43FFF0+8 if=(md)0x300+8
cat --hex (md)0x43FFF0+1 && pause
map --status
pause
map (hd1) (hd0)
map (hd0) (hd1)
map --hook
root (hd0,0) > nul
chainloader (hd0,0)/ntldr
boot

I also tested Int 15h AH=0x12 (used by NTLDR) which also returned the correct value. So something about the map command other than the contents of the memory seems to be affecting NTLDR.

steve6375 commented 7 years ago

New discovery - I have a Windows XP VHD file. It is booted using this code and works on most systems and VMs.

set ISOC=/_ISO/XPFull.vhd
map --heads=2 --sectors-per-track=18 --mem (md)0x800+4 (99)
map %ISOC% (hd0) > nul || map --mem %ISOC% (hd0)
map --hook
write (99) [FiraDisk]\nStartOptions=disk,vmem=find:%~pnx1,boot;\n\0
root (hd0,0) || rootnoverify (hd0,0)
chainloader /bootmgr || chainloader /BOOTMGR || chainloader /ntldr || chainloader +1 || chainloader (hd0)+1
exit

On the Lenovo IdeaPad 300 - it also fails to boot and gives the NTLDR 0K memory error! map --status confirms it is using same 'bad' area when using (md)0x800+4

Fr To Hm Sm To_C  _H _S    Start_Sector   Sector_Count    DHR
-- -- --  -- -- ---- -- -- ---------------- ---------------- ---
63 FF 01 12 83FF FE 7F 000000000043fff0 0000000000000008 M<S

If I replace line 2 with map --heads=2 --sectors-per-track=18 --mem (md)0x800+0x1100 (99) Then it boots OK (md)0x800+9 also works OK

yaya2007 commented 7 years ago

The following understanding, right? Windows XP uses the last block of 4G memory for caching, and must be 0.

steve6375 commented 7 years ago

I don't know about XP and caching - I don't think NTLDR even gets as far as that. It seems to be looking for Low memory (<1MB) to copy code to. The 0K error message comes from NTLDR, I can see the message string inside NTLDR file. I don't understand why NTLDR does not like that top 4K area of memory (if that is the problem).

It seems that (rd)+n uses bytes not sectors?? Is this a bug?? Why must both rd-size and (rd)+n be used to get NTLDR to fail?

Can you find a laptop/PC that has the same memory map 4K block - it must be a feature of recent Intel CPU/chipset.

yaya2007 commented 7 years ago

My computer, the top of memory is 0xc000 bytes, 48Kb.

yaya2007 commented 7 years ago

4KB is aligned upwards, that is, 8 sector alignment, so

map --mem (md)0x800+9 Sector_count of 0x10

yaya2007 commented 7 years ago
  1. map (md)+n (0) Sector_count = (n+7)/8

  2. map (rd)+n (0) if (rd_size>>9 >= n) Sector_count = (n+7)/8 else Sector_count = (rd_size>>9 + 7)/8

steve6375 commented 7 years ago

Do you think that ignoring any memory block <4MB is a good solution for a fix? If so can you release a new version please?

yaya2007 commented 7 years ago

After further testing, the conclusions are as follows: Using int15/eax=e820, Returns the available memory blocks below 4Gb (4Gb and more available memory blocks are not affected), When the length is zero, Windows XP will prompt: "windows nt has found only 0k low memory. 512k of low memory is required to run windows nt. you may need to upqrade your computer or run a configuration program provided by the manufacturer."