| Both sides previous revision
Previous revision
|
|
review_of_iniload_control_flow [2025-10-30 06:56:32 +0100 Oct Thu] ecm |
review_of_iniload_control_flow [2025-11-11 20:04:01 +0100 Nov Tue] (current) ecm add summaries |
| |
| ===== Signature and entrypoint ===== | ===== Signature and entrypoint ===== |
| | |
| | //Summary//: Provide entrypoint for the lDOS load protocol. Clamps load end segment. |
| |
| https://hg.pushbx.org/ecm/ldosboot.exp/file/fada37de0070/iniload.asm#l1375 Offset: 1020, signature "lDXX". The "lD" is checked by recent lDOS compatible loaders, the "XX" is two nonblank printable ASCII text bytes to identify the payload, checked in https://hg.pushbx.org/ecm/ldosboot.exp/file/fada37de0070/iniload.asm#l259 | https://hg.pushbx.org/ecm/ldosboot.exp/file/fada37de0070/iniload.asm#l1375 Offset: 1020, signature "lDXX". The "lD" is checked by recent lDOS compatible loaders, the "XX" is two nonblank printable ASCII text bytes to identify the payload, checked in https://hg.pushbx.org/ecm/ldosboot.exp/file/fada37de0070/iniload.asm#l259 |
| |
| ===== Initialise memory and set up stack ===== | ===== Initialise memory and set up stack ===== |
| | |
| | //Summary//: Sets up a new stack and two buffers in the LMA top reservation area (20 KiB left free by prior loader). Copies over the command line (if any), the Load Stack Variables, and the boot sector including a BPB. |
| |
| https://hg.pushbx.org/ecm/ldosboot.exp/file/fada37de0070/iniload.asm#l1453 **init_memory**, gets Low Memory Area size using int 12h and optionally adjusts it by calling the RPL. Reserves two 8 KiB buffers below the memory top, using the higher buffer as sector segment if it doesn't cross a 64 KiB boundary. Otherwise the lower buffer is used as sector segment. In any case, the other buffer is used as FAT segment. | https://hg.pushbx.org/ecm/ldosboot.exp/file/fada37de0070/iniload.asm#l1453 **init_memory**, gets Low Memory Area size using int 12h and optionally adjusts it by calling the RPL. Reserves two 8 KiB buffers below the memory top, using the higher buffer as sector segment if it doesn't cross a 64 KiB boundary. Otherwise the lower buffer is used as sector segment. In any case, the other buffer is used as FAT segment. |
| |
| ===== Initialise file system ===== | ===== Initialise file system ===== |
| | |
| | //Summary//: Determines whether the file system is FAT12, FAT16, or FAT32. This may involve calculating the amount of data clusters. If need be, and FAT12 is detected, the full FAT is loaded. |
| |
| https://hg.pushbx.org/ecm/ldosboot.exp/file/fada37de0070/iniload.asm#l1631 Checks **bpbSectorsPerFAT** for zero to detect FAT32. If not: First, moves up BPBN and boot sector trail to make space for the pseudo-FAT32 EBPB trail. Second, zeroes high words of **lsvFirstCluster** and **lsvFATSector**. Third, inits **ebpbSectorsPerFATLarge** (equal to zero-extended **bpbSectorsPerFAT**) and **ebpbFSFlags** (zero). | https://hg.pushbx.org/ecm/ldosboot.exp/file/fada37de0070/iniload.asm#l1631 Checks **bpbSectorsPerFAT** for zero to detect FAT32. If not: First, moves up BPBN and boot sector trail to make space for the pseudo-FAT32 EBPB trail. Second, zeroes high words of **lsvFirstCluster** and **lsvFATSector**. Third, inits **ebpbSectorsPerFATLarge** (equal to zero-extended **bpbSectorsPerFAT**) and **ebpbFSFlags** (zero). |
| |
| ===== Check and prepare relocation ===== | ===== Check and prepare relocation ===== |
| | |
| | //Summary//: Calculate where the last to-be-loaded sector of the kernel payload should go, and whether the already resident part must be relocated down to satisfy this placement. |
| |
| https://hg.pushbx.org/ecm/ldosboot.exp/file/fada37de0070/iniload.asm#l985 **finish_continue** (in second 512-bytes block), store cx in **lsvFATSeg**. Store paras(**payload.actual_end**) in ax, add para per sector - 1, mask AND with NOT (para per sector - 1), yielding the length of the payload rounded up to the next full sector, in paragraphs. | https://hg.pushbx.org/ecm/ldosboot.exp/file/fada37de0070/iniload.asm#l985 **finish_continue** (in second 512-bytes block), store cx in **lsvFATSeg**. Store paras(**payload.actual_end**) in ax, add para per sector - 1, mask AND with NOT (para per sector - 1), yielding the length of the payload rounded up to the next full sector, in paragraphs. |
| |
| ===== Do relocate ===== | ===== Do relocate ===== |
| | |
| | //Summary//: If deemed necessary, relocate down the resident part. This part is at least 1536 bytes sized, for lDOS load protocol more commonly at least 4 KiB sized. It may be larger than 64 KiB. Relocation is done in two steps: A small relocator stub handles the first up to 64 KiB, then more code is run from the already relocated initial loader code segment. The initial loader is always fully relocated already by the stub. |
| |
| https://hg.pushbx.org/ecm/ldosboot.exp/file/fada37de0070/iniload.asm#l1007 Relocation code, subtract **ldLoadTop** from ax (needed top of last sector loaded), yielding how far in paragraphs we need to relocate down. Get **lsvLoadSeg** into cx, then subtract ax from **lsvLoadSeg** (to relocate it). Negate ax. Add cs to ax, calculating where we have to relocate cs to. If this addition doesn't carry, error out with out of memory. If the result in ax is < 61h, error out with out of memory. Push the result in ax, and call to **finish_relocation**. This puts the near address of **relocate_to** onto the stack, forming a far address that points to **relocate_to** in the relocation destination segment. | https://hg.pushbx.org/ecm/ldosboot.exp/file/fada37de0070/iniload.asm#l1007 Relocation code, subtract **ldLoadTop** from ax (needed top of last sector loaded), yielding how far in paragraphs we need to relocate down. Get **lsvLoadSeg** into cx, then subtract ax from **lsvLoadSeg** (to relocate it). Negate ax. Add cs to ax, calculating where we have to relocate cs to. If this addition doesn't carry, error out with out of memory. If the result in ax is < 61h, error out with out of memory. Push the result in ax, and call to **finish_relocation**. This puts the near address of **relocate_to** onto the stack, forming a far address that points to **relocate_to** in the relocation destination segment. |
| |
| ===== Walk file loop to load remaining parts of the payload ===== | ===== Walk file loop to load remaining parts of the payload ===== |
| | |
| | //Summary//: The initial loader concludes, if necessary, by walking the FAT chain of the load file to completely load the kernel payload. At first an appropriate amount of data sectors is skipped, after which all additionally needed data sectors are read. |
| |
| https://hg.pushbx.org/ecm/ldosboot.exp/file/fada37de0070/iniload.asm#l1070 **finish_load**, in second 512-bytes block. Get paras(**payload.actual_end**) from the stack. Add cs to it. Set **ldLoadUntilSeg** to result. Check whether **lsvLoadSeg** is already as high or higher than **ldLoadUntilSeg**, if yes branch to **loaded_all**. If no, set **ldLoadingSeg** to cs, get **lsvFirstCluster**, run **check_clust**, and error out if the cluster is invalid (0, 1, or beyond maximum for this FAT type). | https://hg.pushbx.org/ecm/ldosboot.exp/file/fada37de0070/iniload.asm#l1070 **finish_load**, in second 512-bytes block. Get paras(**payload.actual_end**) from the stack. Add cs to it. Set **ldLoadUntilSeg** to result. Check whether **lsvLoadSeg** is already as high or higher than **ldLoadUntilSeg**, if yes branch to **loaded_all**. If no, set **ldLoadingSeg** to cs, get **lsvFirstCluster**, run **check_clust**, and error out if the cluster is invalid (0, 1, or beyond maximum for this FAT type). |
| |
| ===== Final setup after payload file data completely loaded ===== | ===== Final setup after payload file data completely loaded ===== |
| | |
| | //Summary//: The BPB and load command line are cleaned up, and then the code flow is transferred to the fully loaded kernel payload. |
| |
| https://hg.pushbx.org/ecm/ldosboot.exp/file/fada37de0070/iniload.asm#l2507 **loaded_all** and **loaded_all.2stack**, behind **end3**. Check **bpbSectorsPerFAT** equals zero to determine if FAT32. If not, zero out several EBPB fields in the pseudo-FAT32 EBPB created for FAT12 and FAT16 earlier. Copy the query patch value into **ldQueryPatchValue** for next stage. | https://hg.pushbx.org/ecm/ldosboot.exp/file/fada37de0070/iniload.asm#l2507 **loaded_all** and **loaded_all.2stack**, behind **end3**. Check **bpbSectorsPerFAT** equals zero to determine if FAT32. If not, zero out several EBPB fields in the pseudo-FAT32 EBPB created for FAT12 and FAT16 earlier. Copy the query patch value into **ldQueryPatchValue** for next stage. |