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