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 19 static 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 */ 32 int 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 } 98 99 /* 100 * Find a boolean option (like quiet,noapic,nosmp....) 101 * 102 * Returns the position of that option (starts counting with 1) 103 * or 0 on not found 104 */ 105 int cmdline_find_option_bool(const char *option) 106 { 107 u32 cmdline_ptr = boot_params.hdr.cmd_line_ptr; 108 addr_t cptr; 109 char c; 110 int pos = 0, wstart = 0; 111 const char *opptr = NULL; 112 enum { 113 st_wordstart, /* Start of word/after whitespace */ 114 st_wordcmp, /* Comparing this word */ 115 st_wordskip, /* Miscompare, skip */ 116 } state = st_wordstart; 117 118 if (!cmdline_ptr || cmdline_ptr >= 0x100000) 119 return -1; /* No command line, or inaccessible */ 120 121 cptr = cmdline_ptr & 0xf; 122 set_fs(cmdline_ptr >> 4); 123 124 while (cptr < 0x10000) { 125 c = rdfs8(cptr++); 126 pos++; 127 128 switch (state) { 129 case st_wordstart: 130 if (!c) 131 return 0; 132 else if (myisspace(c)) 133 break; 134 135 state = st_wordcmp; 136 opptr = option; 137 wstart = pos; 138 /* fall through */ 139 140 case st_wordcmp: 141 if (!*opptr) 142 if (!c || myisspace(c)) 143 return wstart; 144 else 145 state = st_wordskip; 146 else if (!c) 147 return 0; 148 else if (c != *opptr++) 149 state = st_wordskip; 150 break; 151 152 case st_wordskip: 153 if (!c) 154 return 0; 155 else if (myisspace(c)) 156 state = st_wordstart; 157 break; 158 } 159 } 160 161 return 0; /* Buffer overrun */ 162 } 163