YaK:: NitrOS9 Level 2 : Example of SCF calling F$Move [Changes]   [Calendar]   [Search]   [Index]   [PhotoTags]   

NitrOS9 Level 2: Example of SCF calling F$Move

Using a NitrOS9 kernel built from https://github.com/n6il/nitros9 using level2/coco3

Here you see an example of SFC using F$Move to copy 32 bytes from $1F06 in Task 2 (a user process) to $60E0 in Task 0 (the kernel space).

How to read the trace:

1. The instruction is disassembled in {curly braces}

2. If the assembly source line can be found, it is in {{double curlies}}

3. The first word (like "scf.077c55c62e"+043f) means we are in module scf (the version with length $077c and CRC 55c62e) at offset $043f.

4. The third word (like aa5b:3530) means the PC was at $aa5b and the instruction there is $3530.

5. The other register values are those AFTER the instruction ran.

Whenever a branch is taken (the PC value changes), the hardware MMU is shown: "mmu:1" means the MMU is enabled. "task:0" means it's using task 0. Then the 16 mapping bytes are shown.

HERE IS THE TRACE (hit [Ctrl -] a few times to fit the long lines on your screen):

  • example-of-SCF-calling-F-dollar-Move.txt


    [7:15 PM]strick: I made a trace (with my own emulator) of an example F$Move execution, and it appears it would be capable of copying from one user process U1's address space, to a different user process U2's address space, if they didn't share the same task number 2 (when each is executing) in the small set of Task numbers actually being used. To be explicit, by Task Number, I mean those numbers being read from P$Task, or D.SysTsk, and being passed to F$Move. The trace is linked near the bottom of this explanatory page: http://wiki.yak.net/1165

    [7:25 PM]strick: Things to notice: If we number the mappable 8K blocks as {0, 1, 2, 3, 4, 5, 6, 7}, we know the "krn" module is in block 7 (above $E000). We disable interrupts around a region of code in which we change the MMU registers (look for the GIME MmuMap lines). I don't see an instance of the S stack being used while in that region! The main loop copies 2-byte words, but is unrolled 4 times, so 8 bytes copied per loop.

    [7:26 PM]strick: The copy is always from mappable block 6 to block 5. It also depends on block 7 (for the program) and block 0 (for a static variable). So while interrupts are off, we alter the maps for block 6 ($C000) to the source physical RAM, and block 5 ($A000) to be the destination physical RAM.

    [7:27 PM]strick: So those mappings could have been two different user processes, if it weren't using the same task number 2 for both of them :(

    [8:50 PM]strick: D'oh! I think the answer will lie in 5 obscure kernel-only system calls: F${ResTsk, RelTsk, AllTsk, SetTsk, DelTsk}. The first two are probably what I want. The last 3 are all in terms of the process descriptor, for forging and destroying processes. The first two just reserve and release a task number, and I can probably do that just long enough to call F$Move. And who uses task 3 today? RBF does, krnp2 for process creation, and module loading uses it. If you grep the sources for those F[$]...Tsk sys calls, there are not that many instances.

  • (unless otherwise marked) Copyright 2002-2014 YakPeople. All rights reserved.
    (last modified 2023-01-07)       [Login]
    (No back references.)