Let's start with traditional "lame excuses". The functions, OS operating peculiarities, and algorithms that we describe here are poorly documented or not documented at all. Information mined from various sources turned out partially controversial. I tried to put all the pieces together, but I cannot guarantee that I made no mistakes. My attempts to contact people, who know all ins and outs about the OS modules we discuss here failed - too many years have passed. In some cases I had nothing to do but to reconstruct things, as if recreating a dinosaur by several bones. So if you find a mistake or inaccuracy, I'll appreciate your remarks. And now let's return to our "muttons".
Even though Windows 98 and Windows Me are certainly obsolete operating systems, they are still installed on a lot of computers. There are various reasons for it - from old computers, which are too slow to run modern OS, to software and hardware, which are incompatible with Windows 2000 and XP.
While there will be only one problem on old computers with memory - its insufficient capacity, the new computers will face more complex problems.
For example, a company uses an old computer to run some book-keeping program, written many years ago and still good for its users. But the trouble is, the old computer has been broken and the program won't run on a new computer under XP. Or, you have an old good scanner, which you use from time to time. But there are no WinXP drivers for this scanner and you don't want to throw it away and buy a new model. That's not fair - it works fine!
In these cases the most obvious solution is to install Windows 98 or Windows Me on a new computer: either in a double OS configuration, or as an only OS.
But if your computer is equipped with a lot of memory, these operating systems may fail to install, or may freeze in operation. Forums are full of assertions that Windows 98 cannot use more than 512 MB of memory.
Let's try to investigate the issue. Let's discard cases, when there are no Windows 98 drivers for the new hardware (in this article Win98 will mean three operating systems: Win98, Win98SE and WinMe, if not explicitly expressed otherwise), hyperthreaded operations in Pentium 4 processors are not disabled, etc. We shall touch upon a single case - Windows 98 operation peculiarities with large memory amounts installed.
You will usually have no problems, if the memory capacity does not exceed 512 MB. The system may sometimes freeze with a lesser memory capacity, in case of a bad hardware configuration, when using programs that require little memory, but process a lot of data. But it happens rather seldom and is usually written off to system glitches.
But if you have more than 512 MB installed, the problems start appearing more often, up to constant freezes. You sometimes even cannot install or start up a system, if the memory was added after the installation. Your computer may also fall into continuous rebooting.
Removing the "extra" memory modules is usually a radical effective remedy, all the problems vanish as if by magic. But this solution is not always satisfactory - a rare user will agree to disassemble his or her computer and remove memory before booting into Win98 and then reinstall it before booting into WinXP.
What will advanced users do in such a situation? Right you are! They will open Microsoft Knowledge Base web site. With some web search skills, a user will quickly find articles devoted to this or similar problem: 184447, 253912, 304943, 311871.
You risk feeling your head in a whirl after you read them all. So let's find out what these articles are about and how we should interpret them.
After a thorough analysis, we have dropped Article 311871. It differs very much in style and completeness from the others. We can safely assume that it's written by one of my MVP colleagues, who certainly knows Windows 98 well, but not intimate with its innards.
The assumption that this operating system is not designed for 1 GB of RAM is wrong. It was designed to use up to 2 GB, but the real upper limit (due to solutions, inherited from previous versions) is usually lower.
I actually witnessed (indirectly, in a forum) the very first case of abnormal Windows 98 operation with large memory amounts installed. In February 1998, one of beta testers tried to install Windows 98 (RC0 I believe, that is RC, not a beta version, but not a release either) on a server with 1 GB of memory. In the process of installation he saw a blue screen informing about insufficient memory to initialize Windows. The installation continued only after the memory capacity was reduced to 928 MB.
None of the developers replied that the system was not designed for 1 GB of memory. On the contrary, the answer was something like that: "The system is designed to use up to 2 GB of memory, so this is obviously a bug. We are not going to fix it right now, as we have too little time before the release date and ordinary users will never come across this problem". If we recall typical PC configurations of that time, this assertion was certainly true. I will just add that this gigabyte of memory installed on the ill-starred server was made up of 16 MB modules.
Other articles in the knowledge base speak of limiting the disk cache to 512 MB as well as limiting RAM to 1 GB, 768 MB or even to 512 MB - the amount differs from article to article.
Article 253912 briefly mentions address allocation in the fourth gigabyte, it also dwells on how to limit the cache size. But Article 304943 runs that limiting cache won't help in some cases, you will have to limit the amount of memory used.
So, the knowledge base confirms that Windows may fail to startup or may be unstable, when working with large amounts of memory installed. But what's the reason? The developers were definitely sure about two gigabytes.
OK, it's crystal clear that it's a dark issue. Nobody knows anything for sure. If anyone knows, he doesn't tell it. So, cutting down or physically reducing RAM is often presented as the only effective solution. Let's try to understand the problem inside out.
We'll start with describing how Windows uses memory.
32-bit address space in 80386 processors and higher is divided into memory pages, 4 KB each. Each page is controlled independently of the others. There may be a lot of such address spaces, but the real (physical) address space is available only to the system kernel and drivers. Only they can address physical memory directly. Other system components and all applications work in virtual address spaces, with virtual addresses.
"Virtual memory" is an ambiguous notion. It's often used as an antonym of "physical memory". But in the general case, virtualization is a form of abstraction from a real device. A program can be obviously executed only from physical memory, not when its code is unloaded to a swap file. But in general, the program itself cannot detect whether its parts are in physical memory or unloaded to a disk. It also cannot detect where exactly in physical memory its code and data are - the operating system translates RAM addresses, to which a program addresses within its virtual address space, into the addresses the program actually occupies in physical memory. If a part of virtual memory addressed by a program is unloaded to a swap file, OS suspends operation of the program and loads the necessary page into physical memory. Then the program continues its operation as if the page has always been in memory.
In order to provide such translation, the operating system keeps a special page table, which contains the current correspondence between a virtual page and a location in physical memory or in a swap file, where the data is actually stored.
There are several such tables - a separate table for each program. Various programs may use the same virtual addresses, but each program will have its own correspondence between virtual and real pages, so they will actually address different parts of physical memory.
Speaking of memory allocation, we should note that memory is allocated to a program only at a request. Operating system may refuse to allocate memory to a program, but it cannot allocate more memory than requested. So the questions like "Why doesn't OS allocate all memory to my favorite program, there is so much free memory left" are pointless. You cannot "feed" a program with more memory than needed, that is to make it use more of it.
So, we have already come to know that we should differentiate between physical and virtual address spaces. One of the OS kernel components - memory manager - is responsible (among other things) for translating virtual addresses, used by applications and other kernel components, into real addresses of physical memory.
Windows 98 allocates memory in the following way (see the picture below). The left part shows the address space allocation for programs and the system, the right one displays an example of physical memory allocation.
The entire program address space is divided into four areas. The first area occupies the address range from zero to 4 MB, it's inaccessible for addressing by Windows programs. The situation with DOS programs and device drivers is different, but such peculiarities will lead us astray, so we shall not dwell on details.
The area from 4 MB to 2 GB is the working space for applications. From the point of view of applications, this area is filled with memory amount, necessary for the program (of course, below 2 GB). As it has already been written, each application has its own memory, which has nothing to do with the memory allocated to other programs.
The third gigabyte is used as a shared virtual address space for all programs and the system. Windows loads its graphics core as well as dynamic libraries into this memory area. Of course, these modules are actually located in physical memory in the area of much lower addresses. There just must be a procedure to allow programmers to address system modules. Memory virtualization serves as such a procedure.
The fourth gigabyte (c0000000-ffffffff) is also shared between all programs and the system for several purposes. Firstly, it's used for a kernel, drives, and other modules working on the kernel level (if there are such modules in a system). This area is virtualized like the third gigabyte.
Secondly, an area is allocated in this address space to be used by the disk cache (VCACHE), it's also virtualized.
Thirdly, this very gigabyte contains memory addresses (real, not virtual) of IO devices, which grant direct access to their memory.
Fourthly, it also contains allocated address space for DOS virtual machines.
Let's analyze the usage of the fourth gigabyte in more detail.
Address space for the system kernel is allocated in the same way as for common modules and requires no additional explanations, so we shall proceed straight to describing the disk cache.
More than ten years ago, when Microsoft started developing a disk cache with a dynamically changing size (VCACHE module first appeared in Windows 3.11 for Workgroups, released in 1993), gigabyte memory amounts seemed fantastic. If you didn't know, the first IBM PC, made in 1980, was equipped with 64 KB of RAM. PCs in 1993 usually had 4 MB of memory. Extrapolating these facts to our time, we can expect personal computers in 2006 to have 256 MB of memory. Besides, no one expected this OS and its direct descendants to survive for so long.
Thus, programmers had no reasons to save address space, so they generously assigned the fourth gigabyte for disk cache address space as well. It turned out less taxing to allocate linear virtual address space for variable-size cache and then render it to actually used physical memory via memory manager instead of constantly keeping tabs on allocated memory in the cache module.
That's why part of the address space in the fourth gigabyte is reserved for the disk cache at system startup. Its size depends on the OS version, some hardware characteristics, and the amount of memory installed. It's usually nearly equal to RAM capacity, but its upper limit is 800 MB.
Another responsibility of the fourth gigabyte is to provide access to devices' memory. If you remember DOS times, you know that programs often wrote their data directly into devices' memory, for example into a video adapter (EGA or VGA), in order to improve their performance.
Upgrading to 32-bit CPU mode changed nothing in this respect. Writing data directly is still the fastest method to access a device, the memory addresses of devices were just moved from the first megabyte into the end of the addressed area, to the fourth gigabyte. Besides, there is usually an interlayer (driver) between a program and a device.
The same fourth gigabyte also contains address space for DOS virtual machines, where DOS programs are executed. It requires double redirection: when a program addresses the first megabyte, this address is substituted for a corresponding address of a virtual machine (in the fourth gigabyte). As it's a virtual address, a second redirection is done - to a physical memory address, where a necessary virtual machine page is located. That's the cost for supporting old programs. However, the overheads are not high.
But let's return to the general problems of the fourth gigabyte.
Unlike Windows XP and other NT operating systems, Windows 98 has a single address space for the two senior gigabytes. It's shared between virtual memory and device addresses, it must be sufficient for all uses, or the system operation will be broken.
As a rule, OS cannot affect the usage of memory addresses by devices - in the majority of cases these addresses are fixed in devices.
Now let's see how memory is allocated when Windows starts. The first stage is loading DOS. Then Windows kernel is started from it - VMM.VXD. This file contains a lot of modules, one of them is Virtual Machine Manager (it is responsible for allocating memory), it's a usual DOS program in its structure. But only in its structure and only to be able to run it from DOS. After it's started, it switches the processor to protected mode and uses DOS mostly as a driver of various devices, HDD and video adapter in the first place.
Then Virtual Machine Manager starts loading into memory other modules (drivers) in the VMM.VXD file, drivers, which are mentioned in the registry or system.ini, as well as demanded by previously loaded DOS programs (for example, smartdrv requires loading smartdrv.vxd, stored in smartdrv.exe file, at Windows startup).
It's a vicious circle. A driver must have allocated memory, in order to be loaded into memory. When a memory is allocated, there must be records made in a page table. But in order to allocate space for the page table, there must be memory allocated. That's why Virtual Machine Manager allocated memory in two stages: at first a small memory area (which is sure to be available) is allocated, where driver bodies are loaded. It's also used to build a page table. At the second stage, initialization proper, driver requirements to memory are analyzed and virtual addresses are allocated in the fourth gigabyte.
If we enable boot logging at Windows startup, the log (bootlog.txt) clearly shows these stages. The first two messages for each driver are Loading and LoadSuccess, then Virtual Machine Manager and drivers are initialized: SYSCRITINIT and SYSCRITINTSUCCESS.
The main devourer of the address space is VCACHE, of course. As it has already been mentioned, it requires the address space about as large as the RAM size, but not exceeding 800 MB. Thus, the total requirements of this and other modules may exceed the allocated gigabyte. WinMe is more efficient in this respect. It's more rational in allocating address space, so you'd better use this OS, if you can.
Failed to allocate virtual memory, required by the OS and all drivers, Windows 98 usually shows a message about insufficient memory, while Windows Me reboots (vice versa also happens). But as the address space will be still insufficient, the system will reboot continuously. The log does not contain records about initialization, it breaks off at the stage of loading drivers.
If the deficit of address space is not large, the system may load successfully in Safe Mode, when the number of drivers and the amount of required address space is smaller. But that's not much of a hope.
Sometimes the address space is enough for initialization, but it's almost depleted. In this case the system manages to boot up, but an attempt to start a DOS program results in an error message. If there is a reserve of unused address space, but it's not large, some DOS programs may be started, but those that require more memory will fail to start.
What can be done in case of insufficient address space, when the system fails to startup or DOS programs won't run? Alas, there are only two ways to solve the problem. If you use Windows 98, you may try to upgrade to Windows Me. The second method, more universal, but less productive, consists in limiting the amount of memory used (detailed instructions are given in the end of the article).
You may have a question: if the problem is in insufficient virtual address space for a disk cache, why not limit its size, as described in Microsoft Knowledge Base? Alas, it won't help. The fact is, memory is allocated by Virtual Machine Manager and it looks only into its section of system.ini, [386Enh]. And the cache size is limited in the other section. It influences only the operation of the cache itself, using its allocated address space in particular.
But limiting the disk cache size will most likely be necessary. Why? That's what we shall dwell on now.
So, the operating system starts up, DOS programs can be started as well, but you still cannot work - the system either freezes or shows BSOD after some time. What else does it need?
Let's draw an address space chart of the fourth gigabyte (as it's formed by Windows 98 on the computer of yours truly, some details are omitted to make things simpler). There will be two charts: one for the physical space, the other for virtual.
Note. To avoid possible misunderstandings, we should note that loading Windows kernel without GUI has nothing to do with loading the system with BootGUI=0. In the latter case, Windows proper is not loaded at all, only MS-DOS starts up. Though the documentation mentions Windows real mode kernel.
Note that part of the address range, taken by AGP video adapter, is used twice (if a video adapter uses PCI-E, the picture changes only insignificantly, so let's limit ourselves to the most widespread case).
But if this address range is used by the video adapter, why did the system allocate it for cache virtual memory?
The answer is very simple: modern display drivers consist of two parts, as a rule - a core in the form of a virtual device driver (vxd) and a main part in the form of dynamically loaded libraries. When a system kernel is loaded, it loads just a core of a video adapter. It usually supports only basic functions of a video adapter, approximately on the level of a VGA adapter. That's why it manages well with this address range in the first megabyte or, in addition to it, with a small memory area, occupied by the adapter in the upper addresses of the fourth gigabyte. Initializing memory, Virtual Machine Manager allocates a requested memory range for the video adapter's core. But it cannot get information that this driver will need more of the address space later, when the graphics system as well as all driver files are loaded. So the manager allocated free areas for the VCACHE address space.
Then Windows graphics core is started together with the full driver of the video adapter. This driver initializes all functionality of the video adapter. A physical device appears in the address range used by the adapter. If the same zone is allocated to the disk cache, when VCACHE tries to address it, there appears a conflict between the device driver and the cache. Normal system operation is broken.
What's important, the conflict appears not because this address range is allocated to the cache, but because it starts working with it. It gives us a rather easy way to avoid conflicts: we should just limit the maximum cache size.
As a rule, AGP devices use addresses from e0000000, that is 3.5 GB. Disk cache can then use half a gigabyte. That's the reason for the recommendation to limit the cache size to 524288 KB (512 MB). As a rule, this limitation is effective. But video adapters not always have this very address range. Besides, other devices may act in the same way, e.g. TV tuners. So you may have to limit the cache still further.
Now let's proceed to practical recommendations - how to install Windows 98 on a computer with more than 512 MB of RAM.
Now we should have no problems with large amounts of memory installed.
But in case Windows 98 is the only OS installed on your computer, hear my advice. Don't try to increase your memory amount above the Windows limit. There is sometimes an inverse effect: after you add another memory module, the system may require specifying a lower RAM limit.
There are cases when installing the second gigabyte of memory on computers working with 1 GB of RAM forced users to limit the size of used memory to 900 MB, that is the size of used memory was not increased, but even decreased. WinMe on my computer with 2 GB required only insignificant memory limitation. When I added the third gigabyte of physical memory, I had to limit the memory size, used by Windows, to one gigabyte and a half. That is increasing the actual RAM amount decreased the memory, accessible to the system.
So before investing your money into memory, try to find out how your computer and OS will respond to memory expansion. In practice, the upper limits are usually gigabyte and something for Windows 98 and a tad less than 2 GB for WinMe.
In conclusion I express my thanks to Elmer for the provided computer components to analyze the problem and Mikhail Valerianovich Zhilin for his criticism and advice, which only made this article better.
Igor Petrovich Leiko
November 3, 2005.
Write a comment below. No registration needed!