Page 1 of 1

Has anyone ported busybox for their OS?

Posted: Thu May 21, 2015 11:15 am
by Hellbender
Now that my init loads, I was thinking what would be the next sensible thing to do next. Having busybox would bring so much to the table, so I was thinking about porting few modules to pure POSIX and adding the required support to my OS (say, login module for starters). Soooo,

anyone with experience, tips, suggestions ("don't do it, its a total mess", or what)?

Re: Has anyone ported busybox for their OS?

Posted: Fri May 22, 2015 11:59 am
by osdever
Hellbender wrote:Now that my init loads, I was thinking what would be the next sensible thing to do next. Having busybox would bring so much to the table, so I was thinking about porting few modules to pure POSIX and adding the required support to my OS (say, login module for starters). Soooo,

anyone with experience, tips, suggestions ("don't do it, its a total mess", or what)?
You'll need a working full C library (like Newlib). If you really need it, you can do it, but it will take really long time.

Re: Has anyone ported busybox for their OS?

Posted: Thu May 28, 2015 9:32 am
by Hellbender
I'm documenting my progress so far, in case someone else decides to do this.

I ended by building the whole busybox support library (libbb) but as a hindsight, I should have removed ALL .c files from the library, and then added them back when/if any applets would depend on them.

Busybox supports cross-compiling just fine, as long as you have tool chain ready. Instructions are in their FAQ.
Out-of-source builds work. Start by configuring minimal system, like this:

Code: Select all

make KBUILD_SRC=../busybox-1.23.2 -f ../busybox-1.23.2/Makefile CROSS_COMPILE=i686-hellbender- allnoconfig
This disables all busybox 'applet' but their libbb is monolithic and is fully built even when applets don't use those features. The library requires quite extensive set of headers to compile. I started with pretty empty libc and ended up with the following standard headers:
  • libc/include/arpa/inet.h
    libc/include/assert.h
    libc/include/ctype.h
    libc/include/dirent.h
    libc/include/errno.h
    libc/include/fcntl.h
    libc/include/float.h
    libc/include/grp.h
    libc/include/inttypes.h
    libc/include/libgen.h
    libc/include/limits.h
    libc/include/locale.h
    libc/include/math.h
    libc/include/net/if.h
    libc/include/netdb.h
    libc/include/netinet/in.h
    libc/include/poll.h
    libc/include/pthread.h
    libc/include/pwd.h
    libc/include/sched.h
    libc/include/semaphore.h
    libc/include/setjmp.h
    libc/include/signal.h
    libc/include/spawn.h
    libc/include/stddef.h
    libc/include/stdint.h
    libc/include/stdio.h
    libc/include/stdlib.h
    libc/include/string.h
    libc/include/strings.h
    libc/include/sys/keymap.h
    libc/include/sys/mman.h
    libc/include/sys/param.h
    libc/include/sys/select.h
    libc/include/sys/socket.h
    libc/include/sys/stat.h
    libc/include/sys/time.h
    libc/include/sys/types.h
    libc/include/sys/uio.h
    libc/include/sys/un.h
    libc/include/sys/utsname.h
    libc/include/sys/wait.h
    libc/include/termios.h
    libc/include/time.h
    libc/include/unistd.h
In addition, the library requires few non-standard headers:
  • alloca.h
    byteswap.h
    endian.h
    libc/include/sys/ioctl.h
I ended up adding ioctl for now (although I want to remove it right away), and modified bysybox platform definition file "platform.h" to hack around the rest by adding the following:

Code: Select all

#if defined(__hellbender__)
#include <stdarg.h>
#include <string.h>
#include <strings.h>
#include <sys/types.h>
#include <arpa/inet.h>
#define ONLY_STANDARD_HEADERS
#define	__LITTLE_ENDIAN	1234
#define	__BIG_ENDIAN	4321
#define	__PDP_ENDIAN	3412
#define __BYTE_ORDER __BIG_ENDIAN
#define _SOCKLEN_T_DECLARED
#define bswap_32(x) __builtin_bswap32(x)
#define bswap_64(x) __builtin_bswap64(x)
int initgroups(const char *user, gid_t group);
const char *hstrerror(int err);
extern int h_errno;
int inet_aton(const char *cp, struct in_addr *inp);
struct hostent *gethostbyname(const char *name);
struct hostent *gethostbyaddr(const void *addr, socklen_t len, int type);
int getpagesize(void);
int chroot(const char *path);
#define mempcpy(dest, src, n) (memcpy(dest, src, n) + (n))
#define alloca(size) __builtin_alloca(size)
#endif
Then I surrounded any non-standard includes with "#ifndef ONLY_STANDARD_HEADERS".

In the platform.h, after "Who misses what" -mark, I added the following:

Code: Select all

#if defined(__hellbender__)
# undef __restrict
# undef FAST_FUNC
# define FAST_FUNC
# undef HAVE_CLEARENV
# undef HAVE_FDATASYNC
# undef HAVE_DPRINTF
# undef HAVE_MEMRCHR
# undef HAVE_PTSNAME_R
# undef HAVE_SETBIT
# undef HAVE_SIGHANDLER_T
# undef HAVE_STRCASESTR
# undef HAVE_STRCHRNUL
# undef HAVE_STRSEP
# undef HAVE_STRVERSCMP
# undef HAVE_VASPRINTF
# undef HAVE_USLEEP
# undef HAVE_UNLOCKED_STDIO
# undef HAVE_UNLOCKED_LINE_OPS
# undef HAVE_GETLINE
# undef HAVE_XTABS
# undef HAVE_MNTENT_H
# undef HAVE_NET_ETHERNET_H
# undef HAVE_SYS_STATFS_H
#endif
I also had to remove "missing_syscalls.c", "vfork_daemon_rexec.c", and "xconnect.c". The two latter can be disabled by commenting out their respective lines in "libbb/Kbuild.src", but the first one peculiarly has the build instruction in the .c file itself (change the comment at line 7 to "//kbuild:#lib-y += missing_syscalls.o").

At this point, the libbb was finally compiling, although with a warning from "xfuncs_printf", and it linked a non-functional busybox binary. I enabled "CONFIG_TRUE" and "CONFIG_FALSE" in the ".config" file, and recompiled to get a slightly less useless binary with two applets: true and false.

Next, I have to add binary launching feature to my test-shell to try out the binary in my OS =) I'll report back when I have built and tested more useful applets.