History

kconfig: simplification of scripts/extract-ikconfig

I've rewritten the extract-ikconfig script to extract the kernel configuration from a kernel compiled with CONFIG_IKCONFIG. The main motivation for the rewrite was to remove the dependency on the external C program binoffset.c, which is compiled on the initial run. The binoffset executable is invoked with a relative path, which means that the old script can only be run from the top of the kernel tree, and only when you have write permission in the scripts directory. The new script uses tr/grep/tail/zcat only, and can be invoked from anywhere. The binoffset.c program has been removed. This script requires GNU grep 2.5 (released 2002-03-13) or higher, because the -o option was introduced in that version.

Dick Streefland committed 17 years ago

Commit 7b76bfc1 parent 0eca52a4 files · +44 −248Browse files

Showing the changes to scripts (3 of 4 files). Show all

Unified · Split

3 files
  1. scripts/.gitignore +0 −1
  2. scripts/binoffset.c +0 −163
  3. scripts/extract-ikconfig +44 −83
scripts/.gitignore+0−1
@@ -6,5 +6,4 @@ kallsyms · 5 unmodified lines
6pnmtologo6pnmtologo
7bin2c7bin2c
8unifdef8unifdef
9binoffset
10ihex2fw9ihex2fw
scripts/binoffset.c+0−163
@@ -1,163 +0,0 @@
1/***************************************************************************
2 * binoffset.c
3 * (C) 2002 Randy Dunlap <rdunlap@xenotime.net>
4
5# This program is free software; you can redistribute it and/or modify
6# it under the terms of the GNU General Public License as published by
7# the Free Software Foundation; either version 2 of the License, or
8# (at your option) any later version.
9#
10# This program is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13# GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with this program; if not, write to the Free Software
17# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18
19# binoffset.c:
20# - searches a (binary) file for a specified (binary) pattern
21# - returns the offset of the located pattern or ~0 if not found
22# - exits with exit status 0 normally or non-0 if pattern is not found
23# or any other error occurs.
24
25****************************************************************/
26
27#include <stdio.h>
28#include <stdlib.h>
29#include <string.h>
30#include <errno.h>
31#include <unistd.h>
32#include <fcntl.h>
33#include <sys/types.h>
34#include <sys/stat.h>
35#include <sys/mman.h>
36
37#define VERSION "0.1"
38#define BUF_SIZE (16 * 1024)
39#define PAT_SIZE 100
40
41char *progname;
42char *inputname;
43int inputfd;
44unsigned int bix; /* buf index */
45unsigned char patterns [PAT_SIZE] = {0}; /* byte-sized pattern array */
46int pat_len; /* actual number of pattern bytes */
47unsigned char *madr; /* mmap address */
48size_t filesize;
49int num_matches = 0;
50off_t firstloc = 0;
51
52void usage (void)
53{
54 fprintf (stderr, "%s ver. %s\n", progname, VERSION);
55 fprintf (stderr, "usage: %s filename pattern_bytes\n",
56 progname);
57 fprintf (stderr, " [prints location of pattern_bytes in file]\n");
58 exit (1);
59}
60
61void get_pattern (int pat_count, char *pats [])
62{
63 int ix, err, tmp;
64
65#ifdef DEBUG
66 fprintf (stderr,"get_pattern: count = %d\n", pat_count);
67 for (ix = 0; ix < pat_count; ix++)
68 fprintf (stderr, " pat # %d: [%s]\n", ix, pats[ix]);
69#endif
70
71 for (ix = 0; ix < pat_count; ix++) {
72 tmp = 0;
73 err = sscanf (pats[ix], "%5i", &tmp);
74 if (err != 1 || tmp > 0xff) {
75 fprintf (stderr, "pattern or value error in pattern # %d [%s]\n",
76 ix, pats[ix]);
77 usage ();
78 }
79 patterns [ix] = tmp;
80 }
81 pat_len = pat_count;
82}
83
84void search_pattern (void)
85{
86 for (bix = 0; bix < filesize; bix++) {
87 if (madr[bix] == patterns[0]) {
88 if (memcmp (&madr[bix], patterns, pat_len) == 0) {
89 if (num_matches == 0)
90 firstloc = bix;
91 num_matches++;
92 }
93 }
94 }
95}
96
97#ifdef NOTDEF
98size_t get_filesize (int fd)
99{
100 off_t end_off = lseek (fd, 0, SEEK_END);
101 lseek (fd, 0, SEEK_SET);
102 return (size_t) end_off;
103}
104#endif
105
106size_t get_filesize (int fd)
107{
108 int err;
109 struct stat stat;
110
111 err = fstat (fd, &stat);
112 fprintf (stderr, "filesize: %ld\n", err < 0 ? (long)err : stat.st_size);
113 if (err < 0)
114 return err;
115 return (size_t) stat.st_size;
116}
117
118int main (int argc, char *argv [])
119{
120 progname = argv[0];
121
122 if (argc < 3)
123 usage ();
124
125 get_pattern (argc - 2, argv + 2);
126
127 inputname = argv[1];
128
129 inputfd = open (inputname, O_RDONLY);
130 if (inputfd == -1) {
131 fprintf (stderr, "%s: cannot open '%s'\n",
132 progname, inputname);
133 exit (3);
134 }
135
136 filesize = get_filesize (inputfd);
137
138 madr = mmap (0, filesize, PROT_READ, MAP_PRIVATE, inputfd, 0);
139 if (madr == MAP_FAILED) {
140 fprintf (stderr, "mmap error = %d\n", errno);
141 close (inputfd);
142 exit (4);
143 }
144
145 search_pattern ();
146
147 if (munmap (madr, filesize))
148 fprintf (stderr, "munmap error = %d\n", errno);
149
150 if (close (inputfd))
151 fprintf (stderr, "%s: error %d closing '%s'\n",
152 progname, errno, inputname);
153
154 fprintf (stderr, "number of pattern matches = %d\n", num_matches);
155 if (num_matches == 0)
156 firstloc = ~0;
157 printf ("%ld\n", firstloc);
158 fprintf (stderr, "%ld\n", firstloc);
159
160 exit (num_matches ? 0 : 2);
161}
162
163/* end binoffset.c */
scripts/extract-ikconfig+44−83
@@ -1,92 +1,53 @@
1#!/bin/sh1#!/bin/sh
2# extracts .config info from a [b]zImage file2# ----------------------------------------------------------------------
3# uses: binoffset (new), dd, zcat, strings, grep3# extract-ikconfig - Extract the .config file from a kernel image
4# $arg1 is [b]zImage filename4#
5 5# This will only work when the kernel was compiled with CONFIG_IKCONFIG.
6binoffset="./scripts/binoffset"6#
7test -e $binoffset || cc -o $binoffset ./scripts/binoffset.c || exit 17# The obscure use of the "tr" filter is to work around older versions of
8 8# "grep" that report the byte offset of the line instead of the pattern.
9IKCFG_ST="0x49 0x4b 0x43 0x46 0x47 0x5f 0x53 0x54"9#
10IKCFG_ED="0x49 0x4b 0x43 0x46 0x47 0x5f 0x45 0x44"10# (c) 2009, Dick Streefland <dick@streefland.net>
11dump_config() {11# Licensed under the terms of the GNU General Public License.
12 file="$1"12# ----------------------------------------------------------------------
13 13
14 start=`$binoffset $file $IKCFG_ST 2>/dev/null`14gz1='\037\213\010'
15 [ "$?" != "0" ] && start="-1"15gz2='01'
16 if [ "$start" -eq "-1" ]; then16cf1='IKCFG_ST\037\213\010'
17 return17cf2='0123456789'
18 fi18
19 end=`$binoffset $file $IKCFG_ED 2>/dev/null`19dump_config()
20 [ "$?" != "0" ] && end="-1"
21 if [ "$end" -eq "-1" ]; then
22 return
23 fi
24
25 start=`expr $start + 8`
26 size=`expr $end - $start`
27
28 dd if="$file" ibs=1 skip="$start" count="$size" 2>/dev/null | zcat
29
30 clean_up
31 exit 0
32}
33
34
35usage()
36{
37 echo " usage: extract-ikconfig [b]zImage_filename"
38}
39
40clean_up()
41{20{
42 if [ "$TMPFILE" != "" ]; then21 if pos=`tr "$cf1\n$cf2" "\n$cf2=" < "$1" | grep -abo "^$cf2"`
43 rm -f $TMPFILE22 then
23 pos=${pos%%:*}
24 tail -c+$(($pos+8)) "$1" | zcat -q
25 exit 0
44 fi26 fi
45}27}
46 28
47if [ $# -lt 1 ]29# Check invocation:
30me=${0##*/}
31img=$1
32if [ $# -ne 1 -o ! -s "$img" ]
48then33then
49 usage34 echo "Usage: $me <kernel-image>" >&2
50 exit 135 exit 2
51fi36fi
52 37
53TMPFILE=`mktemp -t ikconfig-XXXXXX` || exit 138# Initial attempt for uncompressed images or objects:
54image="$1"39dump_config "$img"
55 40
56# vmlinux: Attempt to dump the configuration from the file directly41# That didn't work, so decompress and try again:
57dump_config "$image"42tmp=/tmp/ikconfig$$
58 43trap "rm -f $tmp" 0
59GZHDR1="0x1f 0x8b 0x08 0x00"44for pos in `tr "$gz1\n$gz2" "\n$gz2=" < "$img" | grep -abo "^$gz2"`
60GZHDR2="0x1f 0x8b 0x08 0x08"45do
61 46 pos=${pos%%:*}
62ELFHDR="0x7f 0x45 0x4c 0x46"47 tail -c+$pos "$img" | zcat 2> /dev/null > $tmp
63 48 dump_config $tmp
64# vmlinux.gz: Check for a compressed images49done
65off=`$binoffset "$image" $GZHDR1 2>/dev/null`50
66[ "$?" != "0" ] && off="-1"51# Bail out:
67if [ "$off" -eq "-1" ]; then52echo "$me: Cannot find kernel config." >&2
68 off=`$binoffset "$image" $GZHDR2 2>/dev/null`
69 [ "$?" != "0" ] && off="-1"
70fi
71if [ "$off" -eq "0" ]; then
72 zcat <"$image" >"$TMPFILE"
73 dump_config "$TMPFILE"
74elif [ "$off" -ne "-1" ]; then
75 (dd ibs="$off" skip=1 count=0 && dd bs=512k) <"$image" 2>/dev/null | \
76 zcat >"$TMPFILE"
77 dump_config "$TMPFILE"
78
79# check if this is simply an ELF file
80else
81 off=`$binoffset "$image" $ELFHDR 2>/dev/null`
82 [ "$?" != "0" ] && off="-1"
83 if [ "$off" -eq "0" ]; then
84 dump_config "$image"
85 fi
86fi
87
88echo "ERROR: Unable to extract kernel configuration information."
89echo " This kernel image may not have the config info."
90
91clean_up
92exit 153exit 1