General Mechanism
NewtonOS patches work by mapping ROM code to RAM via the Memory Management Unit (MMU). Mapping is done on a per page basis. Each page has a size of 4k. Patching a page requires placing a copy of the original code in the ROM into a patch page, and modifying the data to be patched.
More background information can be found here:
Patchable Areas
Since the NewtonOS ROMs can differ from model to model, certain areas of the ROMs have been fixed in their layout, and designated as patchable areas. The patchable areas usually contain jump tables, providing one level of indirection for function calls. This allows replacing function implementations easily, and helps reducing the number of pages which need to be remapped.
An important aspect of the patchable areas is that they are only sparsely populated: Only the first 128 bytes are usually used. As an example, the patchable area at 0x01a00000 only contains 32 patchable vectors:
0x01a00000 FIQHandler 0x01a00004 IRQHandler 0x01a00008 GenericSWIHandler 0x01a0000c __fp_decode 0x01a00010 PrefetchAbortHandler 0x01a00014 InterruptedSuperMode 0x01a00018 IsFIQMode 0x01a0001c LowLevelCopyEngine 0x01a00020 LowLevelCopyEngineLong 0x01a00024 MonitorEntryGlue 0x01a00028 AirusAL16__FUlP15AirusAParmBlock 0x01a0002c AirusAL__FUlP15AirusAParmBlock 0x01a00030 AL16_GetAttribute2__FUl 0x01a00034 AL16_GetAttribute__FUl 0x01a00038 AL16_NextSet__FP15AirusAParmBlock 0x01a0003c AL16_Shell__FiP15AirusAParmBlock 0x01a00040 AL16_Verify__FP15AirusAParmBlock 0x01a00044 AL_FilterString__FPc 0x01a00048 AL_GetAttribute2__FUl 0x01a0004c AL_GetAttribute__FUl 0x01a00050 AL_NextSet__FP15AirusAParmBlock 0x01a00054 AL_Shell__FUlP15AirusAParmBlock 0x01a00058 AL_Verify__FP15AirusAParmBlock 0x01a0005c Ashortstrcpy__FPUsT1 0x01a00060 Ashortstrlen__FPUs 0x01a00064 Astrchr__FPcc 0x01a00068 Astrcpy__FPcT1 0x01a0006c Astrlen__FPc 0x01a00070 CallAirusA 0x01a00074 ChangeAttribute 0x01a00078 DeleteWord 0x01a0007c DisposDictionary
This is important when looking at the MMU page table patch information: The patch information for the page tables only needs to cover the first 128 bytes of a 4k page, the rest of the page is not relevant. This reduces the size of the patches significantly.
Memory Layouts
A patch links together four different areas:
- The patchable areas in the ROM
- The MMU level 2 tables in RAM
- Patches to the MMU level 2 tables in the patch
- Patch code for the patchable areas in the patch
The links are:
MMU patch information to code in the path: The link is done via the LoadPage macro. It instructs the MMU which page in the patch to refer to. Pages in the patch are numbered 2 to 7 for the ROM patch, and there is one page (number 1) in the REx patch.
- Patched code back to proper virtual address: The mapping of the patched code back into the virtual address space is done implicitly by using calculating the proper offset into the patch table, and using that in the updated code for the patchable area.
Patch pages are coded with position independent code: Mapping page 2 to address 0x01d80000 or to address 0x01da0000 results in the same content.
Anatomy of a Patch
To understand how a patch works in detail, the 717260 patch serves as a good example. The reverse engineered source code is located on SourceForge.
Creating own Patches
Here is a list of potential patches to be developed:
Empty Patch: Purpose is to clear out the MMU patch tables and get the Newton into an unpatched state
Minimum Patch: Purpose is to take the empty patch and patch just one function
Larger Patch: Purpose is to add a new page to the patch
New Page Patch: Purpose is to remap a new page of the pageable area
Changed Page Patch: Purpose is to change an existing patched page

