aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/boot
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2007-07-11 15:18:44 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-12 13:55:55 -0400
commite44c22f65f96217692e1a915032fbe7d22236751 (patch)
tree976498a1a75a88c999f604a6988b7a2ab5e5518f /arch/i386/boot
parent49df18fa3f95a5c988b64e4e20e15372282e96ea (diff)
Command-line parsing code for the new x86 setup code
Simple command-line parser which allows us to access the kernel command line from the setup code. Signed-off-by: H. Peter Anvin <hpa@zytor.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch/i386/boot')
-rw-r--r--arch/i386/boot/cmdline.c97
1 files changed, 97 insertions, 0 deletions
diff --git a/arch/i386/boot/cmdline.c b/arch/i386/boot/cmdline.c
new file mode 100644
index 000000000000..34bb778c4357
--- /dev/null
+++ b/arch/i386/boot/cmdline.c
@@ -0,0 +1,97 @@
1/* -*- linux-c -*- ------------------------------------------------------- *
2 *
3 * Copyright (C) 1991, 1992 Linus Torvalds
4 * Copyright 2007 rPath, Inc. - All Rights Reserved
5 *
6 * This file is part of the Linux kernel, and is made available under
7 * the terms of the GNU General Public License version 2.
8 *
9 * ----------------------------------------------------------------------- */
10
11/*
12 * arch/i386/boot/cmdline.c
13 *
14 * Simple command-line parser for early boot.
15 */
16
17#include "boot.h"
18
19static inline int myisspace(u8 c)
20{
21 return c <= ' '; /* Close enough approximation */
22}
23
24/*
25 * Find a non-boolean option, that is, "option=argument". In accordance
26 * with standard Linux practice, if this option is repeated, this returns
27 * the last instance on the command line.
28 *
29 * Returns the length of the argument (regardless of if it was
30 * truncated to fit in the buffer), or -1 on not found.
31 */
32int cmdline_find_option(const char *option, char *buffer, int bufsize)
33{
34 u32 cmdline_ptr = boot_params.hdr.cmd_line_ptr;
35 addr_t cptr;
36 char c;
37 int len = -1;
38 const char *opptr = NULL;
39 char *bufptr = buffer;
40 enum {
41 st_wordstart, /* Start of word/after whitespace */
42 st_wordcmp, /* Comparing this word */
43 st_wordskip, /* Miscompare, skip */
44 st_bufcpy /* Copying this to buffer */
45 } state = st_wordstart;
46
47 if (!cmdline_ptr || cmdline_ptr >= 0x100000)
48 return -1; /* No command line, or inaccessible */
49
50 cptr = cmdline_ptr & 0xf;
51 set_fs(cmdline_ptr >> 4);
52
53 while (cptr < 0x10000 && (c = rdfs8(cptr++))) {
54 switch (state) {
55 case st_wordstart:
56 if (myisspace(c))
57 break;
58
59 /* else */
60 state = st_wordcmp;
61 opptr = option;
62 /* fall through */
63
64 case st_wordcmp:
65 if (c == '=' && !*opptr) {
66 len = 0;
67 bufptr = buffer;
68 state = st_bufcpy;
69 } else if (myisspace(c)) {
70 state = st_wordstart;
71 } else if (c != *opptr++) {
72 state = st_wordskip;
73 }
74 break;
75
76 case st_wordskip:
77 if (myisspace(c))
78 state = st_wordstart;
79 break;
80
81 case st_bufcpy:
82 if (myisspace(c)) {
83 state = st_wordstart;
84 } else {
85 if (len < bufsize-1)
86 *bufptr++ = c;
87 len++;
88 }
89 break;
90 }
91 }
92
93 if (bufsize)
94 *bufptr = '\0';
95
96 return len;
97}