diff options
Diffstat (limited to 'docs/porting.txt')
-rw-r--r-- | docs/porting.txt | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/docs/porting.txt b/docs/porting.txt new file mode 100644 index 000000000..380645801 --- /dev/null +++ b/docs/porting.txt @@ -0,0 +1,124 @@ +Some notes to help future porters. Replace 'ARCH' with whatever arch +you are hacking on. + +==================== +=== Config Files === +==================== +- create extra/Configs/Config.ARCH + See the other arch files for some good examples. powerpc/sparc/alpha + should be pretty simple templates. +- add ARCH to the 'Target Architecture' list in extra/Configs/Config.in +- Initially you will want to disable shared libraries, since making + the shared library loader work requires you first have basic architecture + support working. Thus you should add ARCH_HAS_NO_SHARED and + ARCH_HAS_NO_LDSO to Config.ARCH's TARGET_ARCH + +==================== +=== libc sysdeps === +==================== +(note: if glibc has already been ported to your arch, you can usually just + copy a lot of files from them rather than coding from scratch) +- create libc/sysdeps/linux/ARCH +- copy Makefile and Makefile.arch from libc/sysdeps/linux/i386/ +- set CSRC and SSRC to nothing in Makefile.arch for now + +- create crt1.S which defines the _start function ... you will probably want + to clear the frame pointer to make gdb happy, and then you will want to call + the funcion __uClibc_main() which takes these parameters: + __uClibc_main(main(), argc, argv, _init(), _fini()) + Initially if you wish to make things easier on yourself, you can disable the + UCLIBC_CTOR_DTOR option and just set the init/fini arguments to NULL. + glibc generally stores this function in libc/sysdeps/ARCH/elf/start.S + +- create these additional files in ARCH/bits/ + + (template versions can be found in common/bits/ for you to tweak) + endian.h fcntl.h setjmp.h stackinfo.h uClibc_arch_features.h wordsize.h + + kernel_types.h should be created based upon linux asm-ARCH/posix_types.h + + copy linux asm-ARCH/stat.h to bits/kernel_stat.h + + create syscalls.h based upon linux's unistd.h / glibc's sysdeps.h ... really + you just want to define the _syscall[0-6] macros. It is important that + these syscalls should be PIC safe (or you should provide a PIC and non-PIC + version) if you wish to properly support shared libraries. + +- at this point, you should have enough to generate a working HELLO WORLD + static binary + +- if you want UCLIBC_CTOR_DTOR support, you will need to create crti.S and + crtn.S files which define function prologues/epilogues. + +- for a more stable static port, you will need to create these files (and + update the Makefile.arch values accordingly) + __longjmp bsd-_setjmp bsd-setjmp brk clone setjmp syscall vfork + usually these are written in assembler, but you may be able to cheat and + write them in C ... see other ports for more information + +==================== +=== ldso sysdeps === +==================== +- elf.h - presumably you've already taught binutils all about the random ELF + relocations your arch needs, so now you need to make sure the defines exist + for uClibc. make sure the EM_### define exists and all of the R_###_### + reloc defines. + +- enable ldso/shared options in your extra/Configs/Config.ARCH file +- you will need to create the following files in ldso/ldso/ARCH/ + dl-startup.h dl-syscalls.h dl-sysdep.h elfinterp.c resolve.S + +- dl-startup.h: + - define the _start function which should call _dl_start which takes just one + parameter ... a pointer to argc (usually on the stack) + glibc stores this function in sysdeps/ARCH/dl-machine.h as RTLD_START + - define the GET_ARGV() macro which calculates the value of argv based upon + the parameter passed to _dl_start (usually it's simply just ARGS+1) + - define PERFORM_BOOTSTRAP_RELOC() macro which will handle just the relocs + that the ldso itself will generate + +- dl-syscalls.h: + if you wrote your bits/syscalls.h file correctly in the libc step above, you + can simply copy this file from another arch and be done ... otherwise you + will have to define the syscall[0-6] macros again, but this time setting + _dl_errno instead of just errno + +- dl-sysdep.h: + misc cruft goes in here ... you want to: + - either define or undefine ELF_USES_RELOCA + - define the INIT_GOT macro + - define MAGIC1 to the EM_### value your ELF arch uses + - define ELF_TARGET to a string name for your arch + - define the do_rem() macro + - define misc ALIGN macro's + - define elf_machine_type_class() macro + - define the inline functions elf_machine_dynamic, elf_machine_load_address, + and elf_machine_relative + glibc stores a bunch of these values in sysdeps/ARCH/dl-machine.h + +- elfinterp.c: + define all the relocation functions ... it's best if you just copy from + another arch which uses the same type of relocations (REL or RELA) and + start from there. + +- resolve.S: + front end of lazy relocation ... define the _dl_linux_resolve symbol which + is called by a PLT entry which has yet to be setup ... you will want to: + - set up arguments for _dl_linux_resolver() + - call _dl_linux_resolver() + - clean up after call + - jump to function address now stored in PLT + glibc stores this function in sysdeps/ARCH/dl-trampoline.S + +- utils/ldd.c - if you want support for ldso cache files (spoiler: you do), + then you'll need to teach ldd a little. generally, the fallback code + should be smart and "just work", but you should be explicit. just pop + it open and add an appropriate ifdef for your arch and set MATCH_MACHINE() + and ELFCLASSM. there are plenty examples and you're (hopefully) smart. + +==================== +=== Misc Cruft === +==================== +- MAINTAINERS - presumably you're going to submit this code back to mainline + and since you're the only one who cares about this arch (right now), you + should add yourself to the toplevel MAINTAINERS file. do it. |