summaryrefslogtreecommitdiff
path: root/docs/PORTING
blob: 1c58c0ca30c3ea985fa587ca14fc4bab9c67be9a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
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
- for now, disable shared libraries
   add HAVE_NO_SHARED and ARCH_HAS_NO_LDSO to Config.ARCH's HAVE_ELF

====================
=== 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())
  for now, you can disable the UCLIBC_CTOR_DTOR option and just set those two
  arguments to NULL
  glibc 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

- at this point, you should have enough to generate a working HELLO WORLD
  static binary (see test/silly/*.c files)

- 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

====================
=== pthread deps ===
====================

TODO: nptl / linuxthreads / linuxthreads.old

====================
=== ldso sysdeps ===
====================
- enable ldso/shared options in your extra/Configs/Config.ARCH file
- you'll need to create these files in ldso/ldso/ARCH/
  dl-debug.h  dl-startup.h  dl-syscalls.h  dl-sysdep.h  elfinterp.c  resolve.S

- dl-debug.h: define string versions of all the relocations of your arch in the
  _dl_reltypes_tab array ... the index should match the actual reloc type, so
  if the value of say R_X86_64_PC16 is 13, then "R_X86_64_PC16" better be at
  index 13 of the array

- 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)
  - 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 libc/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