lh | 9ed821d | 2023-04-07 01:36:19 -0700 | [diff] [blame] | 1 | Some notes to help future porters. Replace 'ARCH' with whatever arch |
| 2 | you are hacking on. |
| 3 | |
| 4 | ==================== |
| 5 | === Config Files === |
| 6 | ==================== |
| 7 | - create extra/Configs/Config.ARCH |
| 8 | See the other arch files for some good examples. powerpc/sparc/alpha |
| 9 | should be pretty simple templates. |
| 10 | - add ARCH to the 'Target Architecture' list in extra/Configs/Config.in |
| 11 | - Initially you will want to disable shared libraries, since making |
| 12 | the shared library loader work requires you first have basic architecture |
| 13 | support working. Thus you should add ARCH_HAS_NO_SHARED and |
| 14 | ARCH_HAS_NO_LDSO to Config.ARCH's TARGET_ARCH |
| 15 | |
| 16 | ==================== |
| 17 | === libc sysdeps === |
| 18 | ==================== |
| 19 | (note: if glibc has already been ported to your arch, you can usually just |
| 20 | copy a lot of files from them rather than coding from scratch) |
| 21 | - create libc/sysdeps/linux/ARCH |
| 22 | - copy Makefile and Makefile.arch from libc/sysdeps/linux/i386/ |
| 23 | - set CSRC and SSRC to nothing in Makefile.arch for now |
| 24 | |
| 25 | - create crt1.S which defines the _start function ... you will probably want |
| 26 | to clear the frame pointer to make gdb happy, and then you will want to call |
| 27 | the funcion __uClibc_main() which takes these parameters: |
| 28 | __uClibc_main(main(), argc, argv, _init(), _fini()) |
| 29 | Initially if you wish to make things easier on yourself, you can disable the |
| 30 | UCLIBC_CTOR_DTOR option and just set the init/fini arguments to NULL. |
| 31 | glibc generally stores this function in libc/sysdeps/ARCH/elf/start.S |
| 32 | |
| 33 | - create these additional files in ARCH/bits/ |
| 34 | |
| 35 | (template versions can be found in common/bits/ for you to tweak) |
| 36 | endian.h fcntl.h setjmp.h stackinfo.h uClibc_arch_features.h wordsize.h |
| 37 | |
| 38 | kernel_types.h should be created based upon linux asm-ARCH/posix_types.h |
| 39 | |
| 40 | copy linux asm-ARCH/stat.h to bits/kernel_stat.h |
| 41 | |
| 42 | create syscalls.h based upon linux's unistd.h / glibc's sysdeps.h ... really |
| 43 | you just want to define the _syscall[0-6] macros. It is important that |
| 44 | these syscalls should be PIC safe (or you should provide a PIC and non-PIC |
| 45 | version) if you wish to properly support shared libraries. |
| 46 | |
| 47 | - at this point, you should have enough to generate a working HELLO WORLD |
| 48 | static binary (see test/silly/*.c files) |
| 49 | |
| 50 | - if you want UCLIBC_CTOR_DTOR support, you will need to create crti.S and |
| 51 | crtn.S files which define function prologues/epilogues. |
| 52 | |
| 53 | - for a more stable static port, you will need to create these files (and |
| 54 | update the Makefile.arch values accordingly) |
| 55 | __longjmp bsd-_setjmp bsd-setjmp brk clone setjmp syscall vfork |
| 56 | usually these are written in assembler, but you may be able to cheat and |
| 57 | write them in C ... see other ports for more information |
| 58 | |
| 59 | ==================== |
| 60 | === pthread deps === |
| 61 | ==================== |
| 62 | |
| 63 | TODO: nptl / linuxthreads / linuxthreads.old |
| 64 | |
| 65 | ==================== |
| 66 | === ldso sysdeps === |
| 67 | ==================== |
| 68 | - elf.h - presumably you've already taught binutils all about the random ELF |
| 69 | relocations your arch needs, so now you need to make sure the defines exist |
| 70 | for uClibc. make sure the EM_### define exists and all of the R_###_### |
| 71 | reloc defines. |
| 72 | |
| 73 | - enable ldso/shared options in your extra/Configs/Config.ARCH file |
| 74 | - you will need to create the following files in ldso/ldso/ARCH/ |
| 75 | dl-debug.h dl-startup.h dl-syscalls.h dl-sysdep.h elfinterp.c resolve.S |
| 76 | |
| 77 | - dl-debug.h: define string versions of all the relocations of your arch in the |
| 78 | _dl_reltypes_tab array ... the index should match the actual reloc type, so |
| 79 | if the value of say R_X86_64_PC16 is 13, then "R_X86_64_PC16" better be at |
| 80 | index 13 of the array |
| 81 | |
| 82 | - dl-startup.h: |
| 83 | - define the _start function which should call _dl_start which takes just one |
| 84 | parameter ... a pointer to argc (usually on the stack) |
| 85 | glibc stores this function in libc/sysdeps/ARCH/dl-machine.h as RTLD_START |
| 86 | - define the GET_ARGV() macro which calculates the value of argv based upon |
| 87 | the parameter passed to _dl_start (usually it's simply just ARGS+1) |
| 88 | - define PERFORM_BOOTSTRAP_RELOC() macro which will handle just the relocs |
| 89 | that the ldso itself will generate |
| 90 | |
| 91 | - dl-syscalls.h: |
| 92 | if you wrote your bits/syscalls.h file correctly in the libc step above, you |
| 93 | can simply copy this file from another arch and be done ... otherwise you |
| 94 | will have to define the syscall[0-6] macros again, but this time setting |
| 95 | _dl_errno instead of just errno |
| 96 | |
| 97 | - dl-sysdep.h: |
| 98 | misc cruft goes in here ... you want to: |
| 99 | - either define or undefine ELF_USES_RELOCA |
| 100 | - define the INIT_GOT macro |
| 101 | - define MAGIC1 to the EM_### value your ELF arch uses |
| 102 | - define ELF_TARGET to a string name for your arch |
| 103 | - define the do_rem() macro |
| 104 | - define misc ALIGN macro's |
| 105 | - define elf_machine_type_class() macro |
| 106 | - define the inline functions elf_machine_dynamic, elf_machine_load_address, |
| 107 | and elf_machine_relative |
| 108 | glibc stores a bunch of these values in libc/sysdeps/ARCH/dl-machine.h |
| 109 | |
| 110 | - elfinterp.c: |
| 111 | define all the relocation functions ... it's best if you just copy from |
| 112 | another arch which uses the same type of relocations (REL or RELA) and |
| 113 | start from there. |
| 114 | |
| 115 | - resolve.S: |
| 116 | front end of lazy relocation ... define the _dl_linux_resolve symbol which |
| 117 | is called by a PLT entry which has yet to be setup ... you will want to: |
| 118 | - set up arguments for _dl_linux_resolver() |
| 119 | - call _dl_linux_resolver() |
| 120 | - clean up after call |
| 121 | - jump to function address now stored in PLT |
| 122 | glibc stores this function in libc/sysdeps/ARCH/dl-trampoline.S |
| 123 | |
| 124 | - utils/ldd.c - if you want support for ldso cache files (spoiler: you do), |
| 125 | then you'll need to teach ldd a little. generally, the fallback code |
| 126 | should be smart and "just work", but you should be explicit. just pop |
| 127 | it open and add an appropriate ifdef for your arch and set MATCH_MACHINE() |
| 128 | and ELFCLASSM. there are plenty examples and you're (hopefully) smart. |
| 129 | |
| 130 | ==================== |
| 131 | === Misc Cruft === |
| 132 | ==================== |
| 133 | - utils/readelf.c - not really needed generally speaking, but might as well |
| 134 | add your arch to the giant EM_* list (describe_elf_hdr) |
| 135 | |
| 136 | - MAINTAINERS - presumably you're going to submit this code back to mainline |
| 137 | and since you're the only one who cares about this arch (right now), you |
| 138 | should add yourself to the toplevel MAINTAINERS file. do it. |