summaryrefslogtreecommitdiff
path: root/recipes/klibc
diff options
context:
space:
mode:
authorDenys Dmytriyenko <denis@denix.org>2009-03-17 14:32:59 -0400
committerDenys Dmytriyenko <denis@denix.org>2009-03-17 14:32:59 -0400
commit709c4d66e0b107ca606941b988bad717c0b45d9b (patch)
tree37ee08b1eb308f3b2b6426d5793545c38396b838 /recipes/klibc
parentfa6cd5a3b993f16c27de4ff82b42684516d433ba (diff)
rename packages/ to recipes/ per earlier agreement
See links below for more details: http://thread.gmane.org/gmane.comp.handhelds.openembedded/21326 http://thread.gmane.org/gmane.comp.handhelds.openembedded/21816 Signed-off-by: Denys Dmytriyenko <denis@denix.org> Acked-by: Mike Westerhof <mwester@dls.net> Acked-by: Philip Balister <philip@balister.org> Acked-by: Khem Raj <raj.khem@gmail.com> Acked-by: Marcin Juszkiewicz <hrw@openembedded.org> Acked-by: Koen Kooi <koen@openembedded.org> Acked-by: Frans Meulenbroeks <fransmeulenbroeks@gmail.com>
Diffstat (limited to 'recipes/klibc')
-rw-r--r--recipes/klibc/files/dash_readopt.patch105
-rw-r--r--recipes/klibc/files/fstype-sane-vfat-and-jffs2-for-1.5.patch63
-rw-r--r--recipes/klibc/files/klibc-config-eabi.patch9
-rw-r--r--recipes/klibc/files/klibc_kexecsyscall.patch11
-rw-r--r--recipes/klibc/files/losetup.patch571
-rw-r--r--recipes/klibc/files/modprobe.patch1985
-rw-r--r--recipes/klibc/files/staging.patch144
-rw-r--r--recipes/klibc/files/wc.patch236
-rw-r--r--recipes/klibc/klibc-common.inc42
-rw-r--r--recipes/klibc/klibc-utils-static_1.5.bb100
-rw-r--r--recipes/klibc/klibc.inc149
-rw-r--r--recipes/klibc/klibc_1.5.bb2
12 files changed, 3417 insertions, 0 deletions
diff --git a/recipes/klibc/files/dash_readopt.patch b/recipes/klibc/files/dash_readopt.patch
new file mode 100644
index 0000000000..49bc087edd
--- /dev/null
+++ b/recipes/klibc/files/dash_readopt.patch
@@ -0,0 +1,105 @@
+Index: klibc-1.5/usr/dash/miscbltin.c
+===================================================================
+--- klibc-1.5.orig/usr/dash/miscbltin.c 2008-03-27 20:38:09.354564817 +0100
++++ klibc-1.5/usr/dash/miscbltin.c 2008-04-04 18:05:32.063364195 +0200
+@@ -46,6 +46,7 @@
+ #include <ctype.h>
+ #include <stdint.h>
+ #include <time.h> /* strtotimeval() */
++#include <termios.h>
+
+ #include "shell.h"
+ #include "options.h"
+@@ -83,6 +84,11 @@
+ int timeout;
+ int i;
+ fd_set set;
++ int n_flag = 0;
++ unsigned int nchars = 0;
++ int silent = 0;
++ struct termios tty, old_tty;
++
+ struct timeval ts, t0, t1, to;
+
+ ts.tv_sec = ts.tv_usec = 0;
+@@ -90,11 +96,18 @@
+ rflag = 0;
+ timeout = 0;
+ prompt = NULL;
+- while ((i = nextopt("p:rt:")) != '\0') {
++ while ((i = nextopt("p:rt:n:s")) != '\0') {
+ switch(i) {
+ case 'p':
+ prompt = optionarg;
+ break;
++ case 'n':
++ nchars = strtoul(optionarg, NULL, 10);
++ n_flag = nchars; /* just a flag "nchars is nonzero" */
++ break;
++ case 's':
++ silent = 1;
++ break;
+ case 't':
+ p = strtotimeval(optionarg, &ts);
+ if (*p || (!ts.tv_sec && !ts.tv_usec))
+@@ -118,6 +131,23 @@
+ sh_error("arg count");
+ if ((ifs = bltinlookup("IFS")) == NULL)
+ ifs = defifs;
++ if (n_flag || silent) {
++ if (tcgetattr(0, &tty) != 0) {
++ /* Not a tty */
++ n_flag = 0;
++ silent = 0;
++ } else {
++ old_tty = tty;
++ if (n_flag) {
++ tty.c_lflag &= ~ICANON;
++ tty.c_cc[VMIN] = nchars < 256 ? nchars : 255;
++ }
++ if (silent) {
++ tty.c_lflag &= ~(ECHO | ECHOK | ECHONL);
++ }
++ tcsetattr(0, TCSANOW, &tty);
++ }
++ }
+ status = 0;
+ startword = 1;
+ backslash = 0;
+@@ -133,13 +163,15 @@
+ ts.tv_sec += t0.tv_sec;
+ }
+ STARTSTACKSTR(p);
+- for (;;) {
++ do {
+ if (timeout) {
+ gettimeofday(&t1, NULL);
+ if (t1.tv_sec > ts.tv_sec ||
+ (t1.tv_sec == ts.tv_sec &&
+ t1.tv_usec >= ts.tv_usec)) {
+ status = 1;
++ if (n_flag)
++ tcsetattr(0, TCSANOW, &old_tty);
+ break; /* Timeout! */
+ }
+
+@@ -156,6 +188,8 @@
+ FD_SET(0, &set);
+ if (select(1, &set, NULL, NULL, &to) != 1) {
+ status = 1;
++ if (n_flag)
++ tcsetattr(0, TCSANOW, &old_tty);
+ break; /* Timeout! */
+ }
+ }
+@@ -191,7 +225,9 @@
+ put:
+ STPUTC(c, p);
+ }
+- }
++ } while (!n_flag || --nchars);
++ if (n_flag || silent)
++ tcsetattr(0, TCSANOW, &old_tty);
+ STACKSTRNUL(p);
+ /* Remove trailing blanks */
+ while ((char *)stackblock() <= --p && strchr(ifs, *p) != NULL)
diff --git a/recipes/klibc/files/fstype-sane-vfat-and-jffs2-for-1.5.patch b/recipes/klibc/files/fstype-sane-vfat-and-jffs2-for-1.5.patch
new file mode 100644
index 0000000000..b52b3e309b
--- /dev/null
+++ b/recipes/klibc/files/fstype-sane-vfat-and-jffs2-for-1.5.patch
@@ -0,0 +1,63 @@
+Index: klibc-1.5/usr/kinit/fstype/fstype.c
+===================================================================
+--- klibc-1.5.orig/usr/kinit/fstype/fstype.c 2008-02-28 00:48:35.319254938 +0100
++++ klibc-1.5/usr/kinit/fstype/fstype.c 2008-02-28 00:52:20.583257793 +0100
+@@ -20,7 +20,7 @@
+ #include <endian.h>
+ #include <netinet/in.h>
+ #include <sys/vfs.h>
+-
++#include <linux/types.h>
+ #define cpu_to_be32(x) __cpu_to_be32(x) /* Needed by romfs_fs.h */
+
+ #include "romfs_fs.h"
+@@ -33,6 +33,12 @@
+ #include "lvm2_sb.h"
+ #include "iso9660_sb.h"
+
++#if __BYTE_ORDER == __BIG_ENDIAN
++#include <linux/byteorder/big_endian.h>
++#else
++#include <linux/byteorder/little_endian.h>
++#endif
++
+ /*
+ * Slightly cleaned up version of jfs_superblock to
+ * avoid pulling in other kernel header files.
+@@ -54,6 +60,27 @@
+ /* Swap needs the definition of block size */
+ #include "swap_fs.h"
+
++static int jffs2_image(const unsigned char *buf, unsigned long *blocks)
++{
++ // Very sloppy! ;-E
++ if (*buf == 0x85 && buf[1] == 0x19)
++ return 1;
++
++ return 0;
++}
++
++static int vfat_image(const unsigned char *buf, unsigned long *blocks)
++{
++ const struct romfs_super_block *sb =
++ (const struct romfs_super_block *)buf;
++ if (!strncmp(buf + 54, "FAT12 ", 8)
++ || !strncmp(buf + 54, "FAT16 ", 8)
++ || !strncmp(buf + 82, "FAT32 ", 8))
++ return 1;
++
++ return 0;
++}
++
+ static int gzip_image(const void *buf, unsigned long long *bytes)
+ {
+ const unsigned char *p = buf;
+@@ -277,6 +304,8 @@
+ {1, "ext3", ext3_image},
+ {1, "ext2", ext2_image},
+ {1, "minix", minix_image},
++ {0, "jffs2", jffs2_image},
++ {0, "vfat", vfat_image},
+ {8, "reiserfs", reiserfs_image},
+ {64, "reiserfs", reiserfs_image},
+ {32, "jfs", jfs_image},
diff --git a/recipes/klibc/files/klibc-config-eabi.patch b/recipes/klibc/files/klibc-config-eabi.patch
new file mode 100644
index 0000000000..86517f0594
--- /dev/null
+++ b/recipes/klibc/files/klibc-config-eabi.patch
@@ -0,0 +1,9 @@
+diff -Nur klibc-1.5/defconfig klibc-1.5p/defconfig
+--- klibc-1.5/defconfig 2007-03-04 02:52:10.000000000 +0100
++++ klibc-1.5p/defconfig 2008-02-08 19:24:22.337127756 +0100
+@@ -5,4 +5,4 @@
+ CONFIG_REGPARM=y
+ # ARM options
+ # CONFIG_KLIBC_THUMB is not set
+-# CONFIG_AEABI is not set
++CONFIG_AEABI=y
diff --git a/recipes/klibc/files/klibc_kexecsyscall.patch b/recipes/klibc/files/klibc_kexecsyscall.patch
new file mode 100644
index 0000000000..9b2dca4738
--- /dev/null
+++ b/recipes/klibc/files/klibc_kexecsyscall.patch
@@ -0,0 +1,11 @@
+--- klibc-1.5/usr/klibc/SYSCALLS.def 2007-03-04 02:52:10.000000000 +0100
++++ klibc.clean/usr/klibc/SYSCALLS.def 2008-02-22 17:12:23.663612084 +0100
+@@ -13,6 +13,8 @@
+ #include <asm/unistd.h>
+ #include <klibc/sysconfig.h>
+ #include <bitsize.h>
++#include <asm/kexec.h>
++long kexec_load(void *, unsigned long , struct kexec_segment *, unsigned long );
+
+ /*
+ * Process-related syscalls
diff --git a/recipes/klibc/files/losetup.patch b/recipes/klibc/files/losetup.patch
new file mode 100644
index 0000000000..77049bd05f
--- /dev/null
+++ b/recipes/klibc/files/losetup.patch
@@ -0,0 +1,571 @@
+Index: klibc-1.5/usr/utils/losetup.c
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ klibc-1.5/usr/utils/losetup.c 2008-03-07 23:13:38.635692852 +0100
+@@ -0,0 +1,485 @@
++/* Originally from Ted's losetup.c */
++
++#define LOOPMAJOR 7
++
++/*
++ * losetup.c - setup and control loop devices
++ */
++
++#include <stdio.h>
++#include <string.h>
++#include <ctype.h>
++#include <fcntl.h>
++#include <errno.h>
++#include <stdlib.h>
++#include <unistd.h>
++#include <sys/ioctl.h>
++#include <sys/stat.h>
++#include <sys/mman.h>
++#include <sys/sysmacros.h>
++#include <string.h>
++
++#include "loop.h"
++
++extern int verbose;
++extern char *progname;
++extern char *xstrdup (const char *s); /* not: #include "sundries.h" */
++extern void error (const char *fmt, ...); /* idem */
++
++/* caller guarantees n > 0 */
++void
++xstrncpy(char *dest, const char *src, size_t n) {
++ strncpy(dest, src, n-1);
++ dest[n-1] = 0;
++}
++
++
++static int
++loop_info64_to_old(const struct loop_info64 *info64, struct loop_info *info)
++{
++ memset(info, 0, sizeof(*info));
++ info->lo_number = info64->lo_number;
++ info->lo_device = info64->lo_device;
++ info->lo_inode = info64->lo_inode;
++ info->lo_rdevice = info64->lo_rdevice;
++ info->lo_offset = info64->lo_offset;
++ info->lo_encrypt_type = info64->lo_encrypt_type;
++ info->lo_encrypt_key_size = info64->lo_encrypt_key_size;
++ info->lo_flags = info64->lo_flags;
++ info->lo_init[0] = info64->lo_init[0];
++ info->lo_init[1] = info64->lo_init[1];
++ if (info->lo_encrypt_type == LO_CRYPT_CRYPTOAPI)
++ memcpy(info->lo_name, info64->lo_crypt_name, LO_NAME_SIZE);
++ else
++ memcpy(info->lo_name, info64->lo_file_name, LO_NAME_SIZE);
++ memcpy(info->lo_encrypt_key, info64->lo_encrypt_key, LO_KEY_SIZE);
++
++ /* error in case values were truncated */
++ if (info->lo_device != info64->lo_device ||
++ info->lo_rdevice != info64->lo_rdevice ||
++ info->lo_inode != info64->lo_inode ||
++ info->lo_offset != info64->lo_offset)
++ return -EOVERFLOW;
++
++ return 0;
++}
++
++
++static int
++show_loop(char *device) {
++ struct loop_info loopinfo;
++ struct loop_info64 loopinfo64;
++ int fd, errsv;
++
++ if ((fd = open(device, O_RDONLY)) < 0) {
++ int errsv = errno;
++ fprintf(stderr, "loop: can't open device %s: %s\n",
++ device, strerror (errsv));
++ return 2;
++ }
++
++ if (ioctl(fd, LOOP_GET_STATUS64, &loopinfo64) == 0) {
++
++ loopinfo64.lo_file_name[LO_NAME_SIZE-2] = '*';
++ loopinfo64.lo_file_name[LO_NAME_SIZE-1] = 0;
++ loopinfo64.lo_crypt_name[LO_NAME_SIZE-1] = 0;
++
++ printf("%s: [%04llx]:%llu (%s)",
++ device, loopinfo64.lo_device, loopinfo64.lo_inode,
++ loopinfo64.lo_file_name);
++
++ if (loopinfo64.lo_offset)
++ printf(", offset %lld", loopinfo64.lo_offset);
++
++ if (loopinfo64.lo_sizelimit)
++ printf(", sizelimit %lld", loopinfo64.lo_sizelimit);
++
++ if (loopinfo64.lo_encrypt_type ||
++ loopinfo64.lo_crypt_name[0]) {
++ char *e = loopinfo64.lo_crypt_name;
++
++ if (*e == 0 && loopinfo64.lo_encrypt_type == 1)
++ e = "XOR";
++ printf(", encryption %s (type %d)",
++ e, loopinfo64.lo_encrypt_type);
++ }
++ printf("\n");
++ close (fd);
++ return 0;
++ }
++
++ if (ioctl(fd, LOOP_GET_STATUS, &loopinfo) == 0) {
++ printf ("%s: [%04x]:%ld (%s)",
++ device, loopinfo.lo_device, loopinfo.lo_inode,
++ loopinfo.lo_name);
++
++ if (loopinfo.lo_offset)
++ printf(", offset %d", loopinfo.lo_offset);
++
++ if (loopinfo.lo_encrypt_type)
++ printf(", encryption type %d\n",
++ loopinfo.lo_encrypt_type);
++
++ printf("\n");
++ close (fd);
++ return 0;
++ }
++
++ errsv = errno;
++ fprintf(stderr, "loop: can't get info on device %s: %s\n",
++ device, strerror (errsv));
++ close (fd);
++ return 1;
++}
++
++int
++is_loop_device (const char *device) {
++ struct stat statbuf;
++
++ return (stat(device, &statbuf) == 0 &&
++ S_ISBLK(statbuf.st_mode) &&
++ major(statbuf.st_rdev) == LOOPMAJOR);
++}
++
++#define SIZE(a) (sizeof(a)/sizeof(a[0]))
++
++char *
++find_unused_loop_device (void) {
++ /* Just creating a device, say in /tmp, is probably a bad idea -
++ people might have problems with backup or so.
++ So, we just try /dev/loop[0-7]. */
++ char dev[20];
++ char *loop_formats[] = { "/dev/loop%d", "/dev/loop/%d" };
++ int i, j, fd, somedev = 0, someloop = 0, permission = 0;
++ struct stat statbuf;
++ struct loop_info loopinfo;
++
++ for (j = 0; j < SIZE(loop_formats); j++) {
++ for(i = 0; i < 256; i++) {
++ sprintf(dev, loop_formats[j], i);
++ if (stat (dev, &statbuf) == 0 && S_ISBLK(statbuf.st_mode)) {
++ somedev++;
++ fd = open (dev, O_RDONLY);
++ if (fd >= 0) {
++ if(ioctl (fd, LOOP_GET_STATUS, &loopinfo) == 0)
++ someloop++; /* in use */
++ else if (errno == ENXIO) {
++ close (fd);
++ return xstrdup(dev);/* probably free */
++ }
++ close (fd);
++ } else if (errno == EACCES)
++ permission++;
++
++ continue;/* continue trying as long as devices exist */
++ }
++ break;
++ }
++ }
++
++ if (!somedev)
++ error("%s: could not find any device /dev/loop#", progname);
++ else if (!someloop && permission)
++ error("%s: no permission to look at /dev/loop#", progname);
++ else if (!someloop)
++ error(
++ "%s: Could not find any loop device. Maybe this kernel "
++ "does not know\n"
++ " about the loop device? (If so, recompile or "
++ "`modprobe loop'.)", progname);
++ else
++ error("%s: could not find any free loop device", progname);
++ return 0;
++}
++
++/*
++ * A function to read the passphrase either from the terminal or from
++ * an open file descriptor.
++ */
++static char *
++xgetpass(int pfd, const char *prompt) {
++ char *pass;
++ int buflen, i;
++
++ pass = NULL;
++ buflen = 0;
++ for (i=0; ; i++) {
++ if (i >= buflen-1) {
++ /* we're running out of space in the buffer.
++ * Make it bigger: */
++ char *tmppass = pass;
++ buflen += 128;
++ pass = realloc(tmppass, buflen);
++ if (pass == NULL) {
++ /* realloc failed. Stop reading. */
++ error("Out of memory while reading passphrase");
++ pass = tmppass; /* the old buffer hasn't changed */
++ break;
++ }
++ }
++ if (read(pfd, pass+i, 1) != 1 ||
++ pass[i] == '\n' || pass[i] == 0)
++ break;
++ }
++
++ if (pass == NULL)
++ return "";
++
++ pass[i] = 0;
++ return pass;
++}
++
++static int
++digits_only(const char *s) {
++ while (*s)
++ if (!isdigit(*s++))
++ return 0;
++ return 1;
++}
++
++int
++set_loop(const char *device, const char *file, unsigned long long offset,
++ const char *encryption, int pfd, int *loopro) {
++ struct loop_info64 loopinfo64;
++ int fd, ffd, mode, i;
++ char *pass;
++
++ mode = (*loopro ? O_RDONLY : O_RDWR);
++ if ((ffd = open(file, mode)) < 0) {
++ if (!*loopro && errno == EROFS)
++ ffd = open(file, mode = O_RDONLY);
++ if (ffd < 0) {
++ perror(file);
++ return 1;
++ }
++ }
++ if ((fd = open(device, mode)) < 0) {
++ perror (device);
++ return 1;
++ }
++ *loopro = (mode == O_RDONLY);
++
++ memset(&loopinfo64, 0, sizeof(loopinfo64));
++
++ xstrncpy(loopinfo64.lo_file_name, file, LO_NAME_SIZE);
++
++ if (encryption && *encryption) {
++ if (digits_only(encryption)) {
++ loopinfo64.lo_encrypt_type = atoi(encryption);
++ } else {
++ loopinfo64.lo_encrypt_type = LO_CRYPT_CRYPTOAPI;
++ snprintf(loopinfo64.lo_crypt_name, LO_NAME_SIZE,
++ "%s", encryption);
++ }
++ }
++
++ loopinfo64.lo_offset = offset;
++
++
++ switch (loopinfo64.lo_encrypt_type) {
++ case LO_CRYPT_NONE:
++ loopinfo64.lo_encrypt_key_size = 0;
++ break;
++ case LO_CRYPT_XOR:
++ pass = xgetpass(pfd, "Password: ");
++ goto gotpass;
++ default:
++ pass = xgetpass(pfd, "Password: ");
++ gotpass:
++ memset(loopinfo64.lo_encrypt_key, 0, LO_KEY_SIZE);
++ xstrncpy(loopinfo64.lo_encrypt_key, pass, LO_KEY_SIZE);
++ memset(pass, 0, strlen(pass));
++ loopinfo64.lo_encrypt_key_size = LO_KEY_SIZE;
++ }
++
++ if (ioctl(fd, LOOP_SET_FD, ffd) < 0) {
++ perror("ioctl: LOOP_SET_FD");
++ return 1;
++ }
++ close (ffd);
++
++ i = ioctl(fd, LOOP_SET_STATUS64, &loopinfo64);
++ if (i) {
++ struct loop_info loopinfo;
++ int errsv = errno;
++
++ i = loop_info64_to_old(&loopinfo64, &loopinfo);
++ if (i) {
++ errno = errsv;
++ perror("ioctl: LOOP_SET_STATUS64");
++ } else {
++ i = ioctl(fd, LOOP_SET_STATUS, &loopinfo);
++ if (i)
++ perror("ioctl: LOOP_SET_STATUS");
++ }
++ memset(&loopinfo, 0, sizeof(loopinfo));
++ }
++ memset(&loopinfo64, 0, sizeof(loopinfo64));
++
++ if (i) {
++ ioctl (fd, LOOP_CLR_FD, 0);
++ close (fd);
++ return 1;
++ }
++ close (fd);
++
++ if (verbose > 1)
++ printf("set_loop(%s,%s,%llu): success\n",
++ device, file, offset);
++ return 0;
++}
++
++int
++del_loop (const char *device) {
++ int fd;
++
++ if ((fd = open (device, O_RDONLY)) < 0) {
++ int errsv = errno;
++ fprintf(stderr, "loop: can't delete device %s: %s\n",
++ device, strerror (errsv));
++ return 1;
++ }
++ if (ioctl (fd, LOOP_CLR_FD, 0) < 0) {
++ perror ("ioctl: LOOP_CLR_FD");
++ return 1;
++ }
++ close (fd);
++ if (verbose > 1)
++ printf("del_loop(%s): success\n", device);
++ return 0;
++}
++
++
++#include <getopt.h>
++#include <stdarg.h>
++
++int verbose = 0;
++char *progname;
++
++static void
++usage(void) {
++ fprintf(stderr, "usage:\n\
++ %s loop_device # give info\n\
++ %s -d loop_device # delete\n\
++ %s -f # find unused\n\
++ %s [-e encryption] [-o offset] {-f|loop_device} file # setup\n",
++ progname, progname, progname, progname);
++ exit(1);
++}
++
++char *
++xstrdup (const char *s) {
++ char *t;
++
++ if (s == NULL)
++ return NULL;
++
++ t = strdup (s);
++
++ if (t == NULL) {
++ fprintf(stderr, "not enough memory");
++ exit(1);
++ }
++
++ return t;
++}
++
++void
++error (const char *fmt, ...) {
++ va_list args;
++
++ va_start (args, fmt);
++ vfprintf (stderr, fmt, args);
++ va_end (args);
++ fprintf (stderr, "\n");
++}
++
++int
++main(int argc, char **argv) {
++ char *p, *offset, *encryption, *passfd, *device, *file;
++ int delete, find, c;
++ int res = 0;
++ int ro = 0;
++ int pfd = -1;
++ unsigned long long off;
++
++
++ delete = find = 0;
++ off = 0;
++ offset = encryption = passfd = NULL;
++
++ progname = argv[0];
++ if ((p = strrchr(progname, '/')) != NULL)
++ progname = p+1;
++
++ while ((c = getopt(argc, argv, "de:E:fo:p:v")) != -1) {
++ switch (c) {
++ case 'd':
++ delete = 1;
++ break;
++ case 'E':
++ case 'e':
++ encryption = optarg;
++ break;
++ case 'f':
++ find = 1;
++ break;
++ case 'o':
++ offset = optarg;
++ break;
++ case 'p':
++ passfd = optarg;
++ break;
++ case 'v':
++ verbose = 1;
++ break;
++ default:
++ usage();
++ }
++ }
++
++ if (argc == 1) {
++ usage();
++ } else if (delete) {
++ if (argc != optind+1 || encryption || offset || find)
++ usage();
++ } else if (find) {
++ if (argc < optind || argc > optind+1)
++ usage();
++ } else {
++ if (argc < optind+1 || argc > optind+2)
++ usage();
++ }
++
++ if (find) {
++ device = find_unused_loop_device();
++ if (device == NULL)
++ return -1;
++ if (verbose)
++ printf("Loop device is %s\n", device);
++ if (argc == optind) {
++ printf("%s\n", device);
++ return 0;
++ }
++ file = argv[optind];
++ } else {
++ device = argv[optind];
++ if (argc == optind+1)
++ file = NULL;
++ else
++ file = argv[optind+1];
++ }
++
++ if (delete)
++ res = del_loop(device);
++ else if (file == NULL)
++ res = show_loop(device);
++ else {
++ if (offset && sscanf(offset, "%llu", &off) != 1)
++ usage();
++ if (passfd && sscanf(passfd, "%d", &pfd) != 1)
++ usage();
++ res = set_loop(device, file, off, encryption, pfd, &ro);
++ }
++ return res;
++}
+Index: klibc-1.5/usr/utils/loop.h
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ klibc-1.5/usr/utils/loop.h 2008-03-07 23:01:49.336694297 +0100
+@@ -0,0 +1,51 @@
++#define LO_CRYPT_NONE 0
++#define LO_CRYPT_XOR 1
++#define LO_CRYPT_DES 2
++#define LO_CRYPT_CRYPTOAPI 18
++
++#define LOOP_SET_FD 0x4C00
++#define LOOP_CLR_FD 0x4C01
++#define LOOP_SET_STATUS 0x4C02
++#define LOOP_GET_STATUS 0x4C03
++#define LOOP_SET_STATUS64 0x4C04
++#define LOOP_GET_STATUS64 0x4C05
++
++#define LO_NAME_SIZE 64
++#define LO_KEY_SIZE 32
++
++#include "my_dev_t.h"
++
++struct loop_info {
++ int lo_number;
++ my_dev_t lo_device;
++ unsigned long lo_inode;
++ my_dev_t lo_rdevice;
++ int lo_offset;
++ int lo_encrypt_type;
++ int lo_encrypt_key_size;
++ int lo_flags;
++ char lo_name[LO_NAME_SIZE];
++ unsigned char lo_encrypt_key[LO_KEY_SIZE];
++ unsigned long lo_init[2];
++ char reserved[4];
++};
++
++/*
++ * Where to get __u8, __u32, __u64? Let us use unsigned char/int/long long
++ * and get punished when someone comes with 128-bit long longs.
++ */
++struct loop_info64 {
++ unsigned long long lo_device;
++ unsigned long long lo_inode;
++ unsigned long long lo_rdevice;
++ unsigned long long lo_offset;
++ unsigned long long lo_sizelimit; /* bytes, 0 == max available */
++ unsigned int lo_number;
++ unsigned int lo_encrypt_type;
++ unsigned int lo_encrypt_key_size;
++ unsigned int lo_flags;
++ unsigned char lo_file_name[LO_NAME_SIZE];
++ unsigned char lo_crypt_name[LO_NAME_SIZE];
++ unsigned char lo_encrypt_key[LO_KEY_SIZE];
++ unsigned long long lo_init[2];
++};
+Index: klibc-1.5/usr/utils/my_dev_t.h
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ klibc-1.5/usr/utils/my_dev_t.h 2008-03-07 23:03:45.148693283 +0100
+@@ -0,0 +1,20 @@
++/* silliness to get dev_t defined as the kernel defines it */
++/* glibc uses a different dev_t */
++
++#include <linux/posix_types.h>
++#include <linux/version.h>
++
++#ifndef KERNEL_VERSION
++#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
++#endif
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(1,3,78)
++/* for i386 - alpha uses unsigned int */
++#define my_dev_t unsigned short
++#else
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,68)
++#define my_dev_t __kernel_dev_t
++#else
++#define my_dev_t __kernel_old_dev_t
++#endif
++#endif
diff --git a/recipes/klibc/files/modprobe.patch b/recipes/klibc/files/modprobe.patch
new file mode 100644
index 0000000000..074b0b6311
--- /dev/null
+++ b/recipes/klibc/files/modprobe.patch
@@ -0,0 +1,1985 @@
+Index: klibc-1.5/usr/utils/Kbuild
+===================================================================
+--- klibc-1.5.orig/usr/utils/Kbuild 2008-03-07 22:01:45.223695348 +0100
++++ klibc-1.5/usr/utils/Kbuild 2008-03-07 22:48:44.660783243 +0100
+@@ -3,8 +3,8 @@
+ #
+
+ progs := chroot dd mkdir mkfifo mknod mount pivot_root umount
+-progs += true false sleep ln nuke minips cat
+-progs += insmod uname halt kill readlink cpio
++progs += true false sleep ln nuke minips cat losetup
++progs += insmod uname halt kill readlink cpio modprobe
+
+ static-y := $(addprefix static/, $(progs))
+ shared-y := $(addprefix shared/, $(progs))
+@@ -52,7 +52,10 @@
+ shared/readlink-y := readlink.o
+ static/cpio-y := cpio.o
+ shared/cpio-y := cpio.o
+-
++static/modprobe-y := modprobe.o
++shared/modprobe-y := modprobe.o
++static/losetup-y := losetup.o
++shared/losetup-y := losetup.o
+ # Additionally linked targets
+ always := static/reboot static/poweroff shared/reboot shared/poweroff
+
+Index: klibc-1.5/usr/utils/list.h
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ klibc-1.5/usr/utils/list.h 2008-03-07 22:33:22.287688586 +0100
+@@ -0,0 +1,238 @@
++/* Stolen from Linux Kernel Source's list.h -- GPL. */
++#ifndef _MODINITTOOLS_LIST_H
++#define _MODINITTOOLS_LIST_H
++
++#undef offsetof
++#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
++
++/**
++ * container_of - cast a member of a structure out to the containing structure
++ *
++ * @ptr: the pointer to the member.
++ * @type: the type of the container struct this is embedded in.
++ * @member: the name of the member within the struct.
++ *
++ */
++#define container_of(ptr, type, member) ({ \
++ const typeof( ((type *)0)->member ) *__mptr = (ptr); \
++ (type *)( (char *)__mptr - offsetof(type,member) );})
++
++/*
++ * Simple doubly linked list implementation.
++ *
++ * Some of the internal functions ("__xxx") are useful when
++ * manipulating whole lists rather than single entries, as
++ * sometimes we already know the next/prev entries and we can
++ * generate better code by using them directly rather than
++ * using the generic single-entry routines.
++ */
++
++struct list_head {
++ struct list_head *next, *prev;
++};
++
++#define LIST_HEAD_INIT(name) { &(name), &(name) }
++
++#define LIST_HEAD(name) \
++ struct list_head name = LIST_HEAD_INIT(name)
++
++#define INIT_LIST_HEAD(ptr) do { \
++ (ptr)->next = (ptr); (ptr)->prev = (ptr); \
++} while (0)
++
++/*
++ * Insert a new entry between two known consecutive entries.
++ *
++ * This is only for internal list manipulation where we know
++ * the prev/next entries already!
++ */
++static inline void __list_add(struct list_head *new,
++ struct list_head *prev,
++ struct list_head *next)
++{
++ next->prev = new;
++ new->next = next;
++ new->prev = prev;
++ prev->next = new;
++}
++
++/**
++ * list_add - add a new entry
++ * @new: new entry to be added
++ * @head: list head to add it after
++ *
++ * Insert a new entry after the specified head.
++ * This is good for implementing stacks.
++ */
++static inline void list_add(struct list_head *new, struct list_head *head)
++{
++ __list_add(new, head, head->next);
++}
++
++/**
++ * list_add_tail - add a new entry
++ * @new: new entry to be added
++ * @head: list head to add it before
++ *
++ * Insert a new entry before the specified head.
++ * This is useful for implementing queues.
++ */
++static inline void list_add_tail(struct list_head *new, struct list_head *head)
++{
++ __list_add(new, head->prev, head);
++}
++
++/*
++ * Delete a list entry by making the prev/next entries
++ * point to each other.
++ *
++ * This is only for internal list manipulation where we know
++ * the prev/next entries already!
++ */
++static inline void __list_del(struct list_head * prev, struct list_head * next)
++{
++ next->prev = prev;
++ prev->next = next;
++}
++
++/**
++ * list_del - deletes entry from list.
++ * @entry: the element to delete from the list.
++ * Note: list_empty on entry does not return true after this, the entry is
++ * in an undefined state.
++ */
++static inline void list_del(struct list_head *entry)
++{
++ __list_del(entry->prev, entry->next);
++}
++
++/**
++ * list_del_init - deletes entry from list and reinitialize it.
++ * @entry: the element to delete from the list.
++ */
++static inline void list_del_init(struct list_head *entry)
++{
++ __list_del(entry->prev, entry->next);
++ INIT_LIST_HEAD(entry);
++}
++
++/**
++ * list_move - delete from one list and add as another's head
++ * @list: the entry to move
++ * @head: the head that will precede our entry
++ */
++static inline void list_move(struct list_head *list, struct list_head *head)
++{
++ __list_del(list->prev, list->next);
++ list_add(list, head);
++}
++
++/**
++ * list_move_tail - delete from one list and add as another's tail
++ * @list: the entry to move
++ * @head: the head that will follow our entry
++ */
++static inline void list_move_tail(struct list_head *list,
++ struct list_head *head)
++{
++ __list_del(list->prev, list->next);
++ list_add_tail(list, head);
++}
++
++/**
++ * list_empty - tests whether a list is empty
++ * @head: the list to test.
++ */
++static inline int list_empty(struct list_head *head)
++{
++ return head->next == head;
++}
++
++static inline void __list_splice(struct list_head *list,
++ struct list_head *head)
++{
++ struct list_head *first = list->next;
++ struct list_head *last = list->prev;
++ struct list_head *at = head->next;
++
++ first->prev = head;
++ head->next = first;
++
++ last->next = at;
++ at->prev = last;
++}
++
++/**
++ * list_splice - join two lists
++ * @list: the new list to add.
++ * @head: the place to add it in the first list.
++ */
++static inline void list_splice(struct list_head *list, struct list_head *head)
++{
++ if (!list_empty(list))
++ __list_splice(list, head);
++}
++
++/**
++ * list_splice_init - join two lists and reinitialise the emptied list.
++ * @list: the new list to add.
++ * @head: the place to add it in the first list.
++ *
++ * The list at @list is reinitialised
++ */
++static inline void list_splice_init(struct list_head *list,
++ struct list_head *head)
++{
++ if (!list_empty(list)) {
++ __list_splice(list, head);
++ INIT_LIST_HEAD(list);
++ }
++}
++
++/**
++ * list_entry - get the struct for this entry
++ * @ptr: the &struct list_head pointer.
++ * @type: the type of the struct this is embedded in.
++ * @member: the name of the list_struct within the struct.
++ */
++#define list_entry(ptr, type, member) \
++ container_of(ptr, type, member)
++
++/**
++ * list_for_each - iterate over a list
++ * @pos: the &struct list_head to use as a loop counter.
++ * @head: the head for your list.
++ */
++#define list_for_each(pos, head) \
++ for (pos = (head)->next; pos != (head); pos = pos->next)
++
++/**
++ * list_for_each_prev - iterate over a list backwards
++ * @pos: the &struct list_head to use as a loop counter.
++ * @head: the head for your list.
++ */
++#define list_for_each_prev(pos, head) \
++ for (pos = (head)->prev; pos != (head); pos = pos->prev)
++
++/**
++ * list_for_each_safe - iterate over a list safe against removal of list entry
++ * @pos: the &struct list_head to use as a loop counter.
++ * @n: another &struct list_head to use as temporary storage
++ * @head: the head for your list.
++ */
++#define list_for_each_safe(pos, n, head) \
++ for (pos = (head)->next, n = pos->next; pos != (head); \
++ pos = n, n = pos-&g