8bit/some 16bit platforms magic XX YY ; magic is the CPU specific magic ; XX and YY are any value ; used to form a jump around the header FZX1 ; format magic (general) loadpage.b ; 0 means 'relocatable' chmem.w ; chmem value (0 all, will change to stack) code.w ; size of code segment data.w ; size of data segment bss.w ; size of the BSS 0.w ; reserved Header is intentionally part of the code so that we load aligned blocks into memory fast. The binary ends with the last block of data (and if need be some zeros of the BSS but see below) Address of code is deliberately passed into the crt0.S from kernel for relocators to be possible Proposed changes: One new magic for split I/D on relevant platforms chmem size will become stack size (only breaks stuff with it set) 0 base will mean 'has relocations' BSS will start with relocation data Rework the header so that code/data/bss are in terms of 256 byte pages. Makes exec a lot simpler (no overflow maths). 0.w will become cpufeature.b cpuspecific.b 6502/68HC11 will use cpuspecific.b for ZP space needed The CPUfeature bit is bits for features not CPU subtypes as o65 does it so 6502 bits 0: NMOS illegals 6502 only 1: 65C02 65C02 and friends 2: 65C02 bitops Rockwell and later WDC C02 3: 65CE02 (Z) 65CE02 4: BCD All but 2A03 5: 65C802/816 6-7 spare for 740 family etc [don't need to cover kernel only bits] This way means we can just do an and and a compare to check compatibility Z80 bits 0: Z80 illegals 1: Z180 2: Z280 3: R800 6809 bits 0: 6309 8086 bits 0: 8087 1: 801C86 instructions (push immediate etc) 2: 80286 3: 80287 68000 bits 0: 68010 1: 68020 2: 68030 3: 68040 4: 68060 5: FPU (might need 2 bits of FPU info) 68HC11 None needed I believe PDP/11 TBD Proposed Relocation Format: 1-255 skip 1-255 bytes and then add the high byte of the base to this address. 0 0 end 0 1-255 skip 1-255 bytes 6502/HC11 has a second set of entries that relocate ZP shifting the ZP offsets by the ZP base of the platform 65C816 if we disallow swapping and support large mode will also need a 3rd pass that updates banks from 0..n to the ones assigned Stick relocation data at end of data segment in a place we load but then count as bss (so brk will go over it). So the loader will consume the relocs and then brk them out of existance. Need to think about compressed binaries and especially for 6502 a fixed lib6502 for the intrinsics code which is a fair size, common to all binaries for the most part, and also could be shared with kernel (eg on Apple IIe) where we have the right mappings. PDP-11 Do we want to just use a.out ? 32bit Uses binfmt_flat with tiny tweaks to avoid loading Linux binaries Entry Conditions & System Calls 6502/65C816: C stack configured in zero page (unrelocated 0/1) 6502 stack set to end of 6502 stack space (may not be $1FF) X holds high byte of load address A holds first zero page value allocated Y undefined Execution begins at first byte of loaded binary Signal vector helper code must be present at offset 20 Need to sort out syscall vector and relocations for it (maybe pass it in Y ?) System calls via jmp ($00fe) [to be fixed for relocation etc] Arguments on C stack (ZP:0 + base) X holds the syscall number Y holds the number of arguments Behaves like a cc65 non fast call, so the syscall unstacks the passed arguments Returns in YX with error code in A and Z clear if no error 68000: A7 is set to the C stack Code is always relocated Other registers are undefined System calls: 32bit pointer / 32bit int unlike smaller ports trap 15 causes a SIGTRAP trap14 (currently - may relocate this) d0 = syscall d1 = arg1 a0 = arg2 a1 = arg3 a2 = arg4 The only register we guarantee to save is A5, thus anything using base relative addressing needs to use A5 as the base because signal handling at the wrong moment may mean all other registers are undefined. This might seem a pain but it saves us a load of clocks! return value is in d0.l and a0.l (for convenience) error code is in d1.w 6809: S is set to the C stack X holds the load address other registers undefined Execution begins at first byte of loaded binary No signal vector helper required System calls are via swi Arguments on the caller stack, call number in D when swi Caller unstacks Returns error code in D, return in X Z80: SP is set to the C stack IY holds the base address (load for relocatables) HL holds the load address System calls: Alternate registers are saved On entry userspace stack holds the syscall arguments On return HL holds the return value and carry is clear On error return HL holds the error and carry is set