All right, here goes. In the spirit of working in the open:
I think I have broken the 1.5 GB limit...
...by 64 MB.
So now it's the 1.5625 GB limit. But it's definitely a start. First, some explanation.
Before the Trampoline (an ELF-contained bootloader inside the Mac OS ROM file) hands control to the NanoKernel, it populates some data structures that describe many levels of the Mac OS environment. The NanoKernel pays the most attention to ConfigInfo, a structure that was formerly part of the RISC ROM but became a dynamic structure on NewWorld Macs. One of the jobs of ConfigInfo is to tell the NanoKernel how to lay out the address space of the blue task. ConfigInfo instructs the NanoKernel to make the main area, starting at address zero, as large as possible given the RAM available. If "Virtual Memory" is enabled then this area will be expanded later in the boot process, at the command of the 68k boot code. But ConfigInfo also instructs the NanoKernel to create these small special-purpose areas:
5fffe000-5fffefff InfoRecord page: contains pointers to structures shared by kernel and userspace
64000000-6417ffff Open Firmware device tree, and Mac II-style "Universal" structures
68fef000-68feffff ConfigInfo
68ffe000-68ffefff Kernel Data Page (kernel actually expands this to ~68ff5000-68ffefff)
68fff000-68ffffff Emulator Data Page
Other areas in the 6 segment are configured differently. The addresses listed might be familiar to anyone who's looked at the NanoKernel log before. But notice in the attached screenshot that the 5fffe000 area is missing, and a 6fffe000 area is present instead. That is because I have inserted code into the NanoKernel that reads the Trampoline's PageMap and edits it. For the curious, here is that code:
macro
PutPMDT &w1, &w2
lisori r31, &w1
stwx r31, r20, r21
addi r21, r21, 4
lisori r31, &w2
stwx r31, r20, r21
addi r21, r21, 4
endm
macro
StartSeg &s
stw r21, NKConfigurationInfo.SegMap32SupInit + 8*&s(r3)
stw r21, NKConfigurationInfo.SegMap32UsrInit + 8*&s(r3)
stw r21, NKConfigurationInfo.SegMap32CPUInit + 8*&s(r3)
stw r21, NKConfigurationInfo.SegMap32OvlInit + 8*&s(r3)
endm
macro
SpecialArea &a
stw r21, NKConfigurationInfo.PageMap&a.Offset(r3)
endm
if RedRover & !Vanilla
; INIT
lwz r20, NKConfigurationInfo.PageMapInitOffset(r3)
add r20, r20, r3
li r21, 0
lwz r29, NKConfigurationInfo.SegMaps + 8*6(r3)
add r29, r29, r20 ; r20 being the base of the pagemap
subi r29, r29, 8
@nt6 lwzu r28, 8(r29)
srwi r28, r28, 28
cmpwi r28, 4
bne @nt6
lwz r28, 0(r29)
lwz r29, 4(r29)
; Now r28/r29 are the 64000000 entry!
; (Important because its physical address and size vary)
; Vanilla page table (probably doesn't vary much between NW Macs)
; StartSeg 0x0
; PutPMDT 0x0000ffff, 0x00000a00
; PutPMDT 0x0000ffff, 0x00000a00
;
; StartSeg 0x1
; PutPMDT 0x0000ffff, 0x00000a00
; PutPMDT 0x0000ffff, 0x00000a00
;
; StartSeg 0x2
; PutPMDT 0x0000ffff, 0x00000a00
; PutPMDT 0x0000ffff, 0x00000a00
;
; StartSeg 0x3
; PutPMDT 0x0000ffff, 0x00000a00
; PutPMDT 0x0000ffff, 0x00000a00
;
; StartSeg 0x4
; PutPMDT 0x0000ffff, 0x00000a00
; PutPMDT 0x0000ffff, 0x00000a00
;
; StartSeg 0x5
; PutPMDT 0x0000fffd, 0x00000a00
; PutPMDT 0x0000fffd, 0x00000a00
; SpecialArea IRP
; PutPMDT 0xfffe0000, 0x00000012
; PutPMDT 0x0000ffff, 0x00000a00
; PutPMDT 0x0000ffff, 0x00000a00
;
; StartSeg 0x6
; stwx r28, r20, r21
; addi r21, r21, 4
; stwx r29, r20, r21
; addi r21, r21, 4
; PutPMDT 0x8fef0000, 0x00003013
; SpecialArea KDP
; PutPMDT 0x8ffe0000, 0x00000011
; SpecialArea EDP
; PutPMDT 0x8fff0000, 0x00000012
; PutPMDT 0x0000ffff, 0x00000a01
; PutPMDT 0x0000ffff, 0x00000a01
; PutPMDT 0x0000ffff, 0x00000a00
;
; StartSeg 0x7
; PutPMDT 0x0000ffff, 0x00000a01
; PutPMDT 0x0000ffff, 0x00000a01
; PutPMDT 0x0000ffff, 0x00000a00
;
; Don't forget to patch logical address fields:
lisori r31, 0x6fffe000
stw r31, NKConfigurationInfo.LA_InfoRecord(r3)
StartSeg 0x0
PutPMDT 0x0000ffff, 0x00000a00
PutPMDT 0x0000ffff, 0x00000a00
StartSeg 0x1
PutPMDT 0x0000ffff, 0x00000a00
PutPMDT 0x0000ffff, 0x00000a00
StartSeg 0x2
PutPMDT 0x0000ffff, 0x00000a00
PutPMDT 0x0000ffff, 0x00000a00
StartSeg 0x3
PutPMDT 0x0000ffff, 0x00000a00
PutPMDT 0x0000ffff, 0x00000a00
StartSeg 0x4
PutPMDT 0x0000ffff, 0x00000a00
PutPMDT 0x0000ffff, 0x00000a00
StartSeg 0x5
PutPMDT 0x0000ffff, 0x00000a00
PutPMDT 0x0000ffff, 0x00000a00
StartSeg 0x6
PutPMDT 0x00003fff, 0x00000a00
PutPMDT 0x00003fff, 0x00000a00
stwx r28, r20, r21 ; Name Registry
addi r21, r21, 4
stwx r29, r20, r21
addi r21, r21, 4
PutPMDT 0x8fef0000, 0x00003013 ; ConfigInfo
SpecialArea KDP
PutPMDT 0x8ffe0000, 0x00000011
SpecialArea EDP
PutPMDT 0x8fff0000, 0x00000012
SpecialArea IRP
PutPMDT 0xfffe0000, 0x00000012
PutPMDT 0x0000ffff, 0x00000a01
PutPMDT 0x0000ffff, 0x00000a01
PutPMDT 0x0000ffff, 0x00000a00
StartSeg 0x7
PutPMDT 0x0000ffff, 0x00000a01
PutPMDT 0x0000ffff, 0x00000a01
PutPMDT 0x0000ffff, 0x00000a00
; Later parts of the table
; (definitely vary between machines)
; StartSeg 0x8
; PutPMDT 0x0000ffff, 0x8000003a
; PutPMDT 0x0000ffff, 0x80000a01
; PutPMDT 0x0000ffff, 0x00000a00
; StartSeg 0x9
; PutPMDT 0x0000000f, 0x9000003a
; PutPMDT 0x0020001f, 0x9002003a
; PutPMDT 0x80007fff, 0x98000032
; PutPMDT 0x0000ffff, 0x90000a01
; PutPMDT 0x0000ffff, 0x00000a00
; StartSeg 0xa
; PutPMDT 0x0000ffff, 0xa0000a01
; PutPMDT 0x0000ffff, 0x00000a00
; StartSeg 0xb
; PutPMDT 0x0000ffff, 0xb0000a01
; PutPMDT 0x0000ffff, 0x00000a00
; StartSeg 0xc
; PutPMDT 0x0000ffff, 0xc0000a01
; PutPMDT 0x0000ffff, 0x00000a00
; StartSeg 0xd
; PutPMDT 0x0000ffff, 0xd0000a01
; PutPMDT 0x0000ffff, 0x00000a00
; StartSeg 0xe
; PutPMDT 0x0000ffff, 0xe0000a01
; PutPMDT 0x0000ffff, 0x00000a00
; StartSeg 0xf
; PutPMDT 0x0000ffff, 0xf000003a
; PutPMDT 0x0000ffff, 0xf0000a01
; PutPMDT 0x0000ffff, 0x00000a00
;stw r21, NKConfigurationInfo.PageMapInitSize(r3)
li r20, 0
li r21, 0
li r31, 0
endif
The effect of the patch is to move the InfoRecord page from the 5 segment to the equivalent location in the 6 segment, and to expand the blue area up to the bottom of the next obstacle, at 64000000. This is a difference of 64 MB.
On its own, this patch crashes my Power Mac (even though it only has 256 MB). This is because the 68k Emulator, which lives in ROM just a few KB north of the NanoKernel, contains a hardcoded constant, 5fffe000, which it uses to fetch the LogicalMemorySize from the NanoKernel's SystemInfo structure. I changed that, and all was well. (Hopefully there are no more subtle crashes waiting to strike. Well-written software should use the NKLocateInfoRecord kernel call instead of hardcoding that location.)
Interestingly, the patch alone did not crash QEMU. QEMU is currently my only way to start Mac OS 9 with the full 2 GB of RAM. (By the way, anyone want to send me 2 GB that will work in my FW800 MDD? I'm hopeless with hardware.) QEMU does not start the Dynamic Recompiling function of the emulator, which is the part that contains the hardcoded constant. I am not yet sure why.
So that's one down and
So, I need testers with 2 GB Macs running Mac OS 9.2.2. Attached is a Mac OS ROM file and a copy of NKLogReader. First, dump the log output of your normal kernel. Then, install the patched Mac OS ROM file. If you get a crash on boot, please take a picture of the kernel log. If it boots up, please get a screenshot of the Finder About window and a kernel dump.
Soon we might bust the 1.5 GB limit completely. Good luck, and have fun.