mu/linux/104new-segment.subx
Kartik K. Agaram 827dd4a7fe start throwing error on duplicate label
One less error that's only in the bootstrap phase.

On the other hand, for simplicity I got rid of the ability to override
the Entry label. One less special case, but we're also going further
from the ability to run subsets of layers. We haven't really been
exercising it for a long time, though (commit 7842, March 2021 when we
made baremetal the default).
2021-08-22 21:09:28 -07:00

89 lines
4.5 KiB
Plaintext

# Create a new segment (pool of memory for allocating chunks from) in the form
# of an *allocation descriptor* that can be passed to the memory allocator
# (defined in a later layer).
#
# Currently an allocation descriptor consists of just the bounds of the pool of
# available memory:
#
# curr: address
# end: address
#
# This isn't enough information to reclaim individual allocations. We can't
# support arbitrary reclamation yet.
== code
# instruction effective address register displacement immediate
# . op subop mod rm32 base index scale r32
# . 1-3 bytes 3 bits 2 bits 3 bits 3 bits 3 bits 2 bits 2 bits 0/1/2/4 bytes 0/1/2/4 bytes
#? Entry: # manual test
#? # var ad/ecx: allocation-descriptor
#? 68/push 0/imm32/limit
#? 68/push 0/imm32/curr
#? 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
#? # new-segment(0x1000, ad)
#? # . . push args
#? 51/push-ecx
#? 68/push 0x1000/imm32
#? # . . call
#? e8/call new-segment/disp32
#? # . . discard args
#? 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
#? # var eax: (addr _) = ad->curr
#? 8b/copy 0/mod/indirect 1/rm32/ecx . . . 0/r32/eax . . # copy *ecx to eax
#? # write to *eax to check that we have access to the newly-allocated segment
#? c7 0/subop/copy 0/mod/direct 0/rm32/eax . . . . . 0x34/imm32 # copy to *eax
#? # syscall_exit(eax)
#? 89/copy 3/mod/direct 3/rm32/ebx . . . 0/r32/eax . . # copy eax to ebx
#? e8/call syscall_exit/disp32
new-segment: # len: int, ad: (addr allocation-descriptor)
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
# . save registers
50/push-eax
53/push-ebx
# copy len to _mmap-new-segment->len
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 0/r32/eax 8/disp8 . # copy *(ebp+8) to eax
89/copy 0/mod/indirect 5/rm32/.disp32 . . 0/r32/eax $_mmap-new-segment:len/disp32 # copy eax to *$_mmap-new-segment:len
# mmap(_mmap-new-segment)
bb/copy-to-ebx _mmap-new-segment/imm32
e8/call syscall_mmap/disp32
# copy {eax, eax+len} to *ad
# . ebx = ad
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 3/r32/ebx 0xc/disp8 . # copy *(ebp+12) to ebx
# . ad->curr = eax
89/copy 0/mod/indirect 3/rm32/ebx . . . 0/r32/eax . . # copy eax to *ebx
# . ad->end = eax+len
03/add 1/mod/*+disp8 5/rm32/ebp . . . 0/r32/eax 8/disp8 . # add *(ebp+8) to eax
89/copy 1/mod/*+disp8 3/rm32/ebx . . . 0/r32/eax 4/disp8 . # copy eax to *(ebx+4)
$new-segment:end:
# . restore registers
5b/pop-to-ebx
58/pop-to-eax
# . epilogue
89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp
5d/pop-to-ebp
c3/return
== data
# various constants used here were found in the Linux sources (search for file mman-common.h)
_mmap-new-segment: # mmap_arg_struct
# addr
0/imm32
$_mmap-new-segment:len:
# len
0/imm32
# protection flags
3/imm32 # PROT_READ | PROT_WRITE
# sharing flags
0x22/imm32 # MAP_PRIVATE | MAP_ANONYMOUS
# fd
-1/imm32 # since MAP_ANONYMOUS is specified
# offset
0/imm32 # since MAP_ANONYMOUS is specified
# . . vim:nowrap:textwidth=0