Changeset ff3b3197 in mainline


Ignore:
Timestamp:
2005-11-25T22:58:38Z (19 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
f4338d2
Parents:
78c32b4
Message:

Implement basic kernel console command recognition.
Commands without arguments are now recognized.

Files:
1 added
10 edited

Legend:

Unmodified
Added
Removed
  • arch/ia32/src/drivers/i8042.c

    r78c32b4 rff3b3197  
    3838#include <console/chardev.h>
    3939#include <console/console.h>
     40#include <macros.h>
    4041
    4142/**
     
    308309                break;
    309310            default:
    310                 letter = (ascii >= 'a') && (ascii <= 'z');
     311                letter = is_lower(ascii);
    311312                capslock = (keyflags & PRESSED_CAPSLOCK) || (lockflags & LOCKED_CAPSLOCK);
    312313                shift = keyflags & PRESSED_SHIFT;
  • generic/include/console/console.h

    r78c32b4 rff3b3197  
    3636
    3737extern __u8 getc(chardev_t *chardev);
    38 extern void gets(chardev_t *chardev, __u8 *buf, size_t buflen);
     38extern count_t gets(chardev_t *chardev, char *buf, size_t buflen);
    3939
    4040#endif /* __CHARDEV_H__ */
  • generic/include/func.h

    r78c32b4 rff3b3197  
    3131
    3232#include <arch/types.h>
     33#include <typedefs.h>
    3334
    3435extern __u32 haltstate;
     
    3637extern void halt(void);
    3738
    38 extern int strcmp(const char *src, const char *dst);
     39extern size_t strlen(const char *str);
     40extern int strcmp(const char *src, const char *dst, size_t len);
    3941
    4042#endif
  • generic/include/main/kconsole.h

    r78c32b4 rff3b3197  
    3030#define __KCONSOLE_H__
    3131
     32#include <typedefs.h>
     33#include <list.h>
     34#include <synch/spinlock.h>
     35
     36enum cmd_arg_type {
     37        ARG_TYPE_INVALID = 0,
     38        ARG_TYPE_INT,
     39        ARG_TYPE_STRING
     40};
     41
     42/** Structure representing one argument of kconsole command line. */
     43struct cmd_arg {
     44        cmd_arg_type_t type;            /**< Type descriptor. */
     45        void *buffer;                   /**< Buffer where to store data. */
     46        size_t buflen;                  /**< Size of the buffer. */
     47};
     48
     49/** Structure representing one kconsole command. */
     50struct cmd_info {
     51        link_t link;                    /**< Command list link. */
     52        spinlock_t lock;                /**< This lock protects everything below. */
     53        const char *name;               /**< Command name. */
     54        const char *description;        /**< Textual description. */
     55        int (* func)(cmd_arg_t *cmd);   /**< Function implementing the command. */
     56        count_t argc;                   /**< Number of arguments. */
     57        cmd_arg_t *argv;                /**< Argument vector. */
     58};
     59
     60extern spinlock_t cmd_lock;
     61extern link_t cmd_head;
     62
     63extern void kconsole_init(void);
    3264extern void kconsole(void *arg);
    3365
     66extern int cmd_register(cmd_info_t *cmd);
     67
    3468#endif
  • generic/include/typedefs.h

    r78c32b4 rff3b3197  
    8282typedef struct chardev chardev_t;
    8383
     84typedef enum cmd_arg_type cmd_arg_type_t;
     85typedef struct cmd_arg cmd_arg_t;
     86typedef struct cmd_info cmd_info_t;
     87
    8488#endif
  • generic/src/console/console.c

    r78c32b4 rff3b3197  
    4545 *
    4646 * @param chardev Character device.
    47  * @param string Buffer where to store string terminated by '\0'.
     47 * @param buf Buffer where to store string terminated by '\0'.
    4848 * @param len Size of the buffer.
     49 *
     50 * @return Number of characters read.
    4951 */
    50 void gets(chardev_t *chardev, __u8 *string, size_t buflen)
     52count_t gets(chardev_t *chardev, char *buf, size_t buflen)
    5153{
    5254        index_t index = 0;
     
    5658                ch = getc(chardev);
    5759                if (ch == '\n') { /* end of string => write 0, return */
    58                         string[index] = '\0';
    59                         return;
     60                        buf[index] = '\0';
     61                        return (count_t) index;
    6062                }
    61                 string[index++] = ch;
     63                buf[index++] = ch;
    6264        }
    63         return;
     65        return (count_t) index;
    6466}
    6567
  • generic/src/lib/func.c

    r78c32b4 rff3b3197  
    3232#include <arch/asm.h>
    3333#include <arch.h>
     34#include <typedefs.h>
    3435
    3536__u32   haltstate = 0; /**< Halt flag */
     
    5253}
    5354
     55/** Return number of characters in a string.
     56 *
     57 * @param str NULL terminated string.
     58 *
     59 * @return Number of characters in str.
     60 */
     61size_t strlen(const char *str)
     62{
     63        int i;
     64       
     65        for (i = 0; str[i]; i++)
     66                ;
     67       
     68        return i;
     69}
    5470
    5571/** Compare two NULL terminated strings
    5672 *
    57  * Do a char-by-char comparment of two NULL terminated strings.
    58  * The strings are considered equal iff they have the same
    59  * length and consist of the same characters.
     73 * Do a char-by-char comparison of two NULL terminated strings.
     74 * The strings are considered equal iff they consist of the same
     75 * characters on the minimum of their lengths and specified maximal
     76 * length.
    6077 *
    6178 * @param src First string to compare.
    6279 * @param dst Second string to compare.
     80 * @param len Maximal length for comparison.
    6381 *
    6482 * @return 0 if the strings are equal, 1 otherwise.
    6583 *
    6684 */
    67 int strcmp(const char *src, const char *dst)
     85int strcmp(const char *src, const char *dst, size_t len)
    6886{
    6987        int i;
    7088       
    7189        i = 0;
    72         while (src[i] == dst[i]) {
    73                 if (src[i] == '\0')
     90        while ((i < len) && (src[i] == dst[i])) {
     91                if ((i == len - 1) || (src[i] == '\0'))
    7492                        return 0;
    7593                i++;
  • generic/src/main/kconsole.c

    r78c32b4 rff3b3197  
    3131#include <console/chardev.h>
    3232#include <print.h>
     33#include <panic.h>
    3334#include <typedefs.h>
    3435#include <arch/types.h>
     36#include <list.h>
     37#include <arch.h>
     38#include <func.h>
     39#include <macros.h>
     40
     41#define MAX_CMDLINE     256
     42
     43/** Simple kernel console.
     44 *
     45 * The console is realized by kernel thread kconsole.
     46 * It doesn't understand any commands on its own, but
     47 * makes it possible for other kernel subsystems to
     48 * register their own commands.
     49 */
     50 
     51/** Locking.
     52 *
     53 * There is a list of cmd_info_t structures. This list
     54 * is protected by cmd_lock spinlock. Note that specially
     55 * the link elements of cmd_info_t are protected by
     56 * this lock.
     57 *
     58 * Each cmd_info_t also has its own lock, which protects
     59 * all elements thereof except the link element.
     60 *
     61 * cmd_lock must be acquired before any cmd_info lock.
     62 * When locking two cmd info structures, structure with
     63 * lower address must be locked first.
     64 */
     65 
     66spinlock_t cmd_lock;    /**< Lock protecting command list. */
     67link_t cmd_head;        /**< Command list. */
     68
     69static cmd_info_t *parse_cmdline(char *cmdline, size_t len);
     70static int cmd_help(cmd_arg_t *cmd);
     71
     72static cmd_info_t help_info;
     73
     74/** Initialize kconsole data structures. */
     75void kconsole_init(void)
     76{
     77        spinlock_initialize(&cmd_lock);
     78        list_initialize(&cmd_head);
     79       
     80        help_info.name = "help";
     81        help_info.description = "List supported commands.";
     82        help_info.func = cmd_help;
     83        help_info.argc = 0;
     84        help_info.argv = NULL;
     85       
     86        spinlock_initialize(&help_info.lock);
     87        link_initialize(&help_info.link);
     88       
     89        if (!cmd_register(&help_info))
     90                panic("could not register command\n");
     91}
     92
     93
     94/** Register kconsole command.
     95 *
     96 * @param cmd Structure describing the command.
     97 *
     98 * @return 0 on failure, 1 on success.
     99 */
     100int cmd_register(cmd_info_t *cmd)
     101{
     102        ipl_t ipl;
     103        link_t *cur;
     104       
     105        ipl = interrupts_disable();
     106        spinlock_lock(&cmd_lock);
     107       
     108        /*
     109         * Make sure the command is not already listed.
     110         */
     111        for (cur = cmd_head.next; cur != &cmd_head; cur = cur->next) {
     112                cmd_info_t *hlp;
     113               
     114                hlp = list_get_instance(cur, cmd_info_t, link);
     115
     116                if (hlp == cmd) {
     117                        /* The command is already there. */
     118                        spinlock_unlock(&cmd_lock);
     119                        interrupts_restore(ipl);
     120                        return 0;
     121                }
     122
     123                /* Avoid deadlock. */
     124                if (hlp < cmd) {
     125                        spinlock_lock(&hlp->lock);
     126                        spinlock_lock(&cmd->lock);
     127                } else {
     128                        spinlock_lock(&cmd->lock);
     129                        spinlock_lock(&hlp->lock);
     130                }
     131               
     132                if ((strcmp(hlp->name, cmd->name, strlen(cmd->name)) == 0)) {
     133                        /* The command is already there. */
     134                        spinlock_unlock(&hlp->lock);
     135                        spinlock_unlock(&cmd->lock);
     136                        spinlock_unlock(&cmd_lock);
     137                        interrupts_restore(ipl);
     138                        return 0;
     139                }
     140               
     141                spinlock_unlock(&hlp->lock);
     142                spinlock_unlock(&cmd->lock);
     143        }
     144       
     145        /*
     146         * Now the command can be added.
     147         */
     148        list_append(&cmd->link, &cmd_head);
     149       
     150        spinlock_unlock(&cmd_lock);
     151        interrupts_restore(ipl);
     152        return 1;
     153}
    35154
    36155/** Kernel console managing thread.
     
    40159void kconsole(void *arg)
    41160{
    42         __u8 buf[CHARDEV_BUFLEN];
     161        char cmdline[MAX_CMDLINE+1];
     162        cmd_info_t *cmd_info;
     163        count_t len;
    43164
    44165        if (!stdin) {
     
    49170        while (true) {
    50171                printf("%s> ", __FUNCTION__);
    51                 gets(stdin, buf, sizeof(buf));
    52                 printf("?\n");
    53         }
    54 }
     172                len = gets(stdin, cmdline, sizeof(cmdline));
     173                cmdline[len] = '\0';
     174                cmd_info = parse_cmdline(cmdline, len);
     175                if (!cmd_info) {
     176                        printf("?\n");
     177                        continue;
     178                }
     179                (void) cmd_info->func(cmd_info->argv);
     180        }
     181}
     182
     183/** Parse command line.
     184 *
     185 * @param cmdline Command line as read from input device.
     186 * @param len Command line length.
     187 *
     188 * @return Structure describing the command.
     189 */
     190cmd_info_t *parse_cmdline(char *cmdline, size_t len)
     191{
     192        index_t start = 0, end = 0;
     193        bool found_start = false;
     194        cmd_info_t *cmd = NULL;
     195        link_t *cur;
     196        ipl_t ipl;
     197        int i;
     198       
     199        for (i = 0; i < len; i++) {
     200                if (!found_start) {
     201                        if (is_white(cmdline[i]))
     202                                start++;
     203                        else
     204                                found_start = true;
     205                } else {
     206                        if (is_white(cmdline[i]))
     207                                break;
     208                }
     209        }
     210        end = i - 1;
     211       
     212        if (!found_start) {
     213                /* Command line did not contain alphanumeric word. */
     214                return NULL;
     215        }
     216
     217        ipl = interrupts_disable();
     218        spinlock_lock(&cmd_lock);
     219       
     220        for (cur = cmd_head.next; cur != &cmd_head; cur = cur->next) {
     221                cmd_info_t *hlp;
     222               
     223                hlp = list_get_instance(cur, cmd_info_t, link);
     224                spinlock_lock(&hlp->lock);
     225               
     226                if (strcmp(hlp->name, &cmdline[start], (end - start) + 1) == 0) {
     227                        cmd = hlp;
     228                        break;
     229                }
     230               
     231                spinlock_unlock(&hlp->lock);
     232        }
     233       
     234        spinlock_unlock(&cmd_lock);     
     235       
     236        if (!cmd) {
     237                /* Unknown command. */
     238                interrupts_restore(ipl);
     239                return NULL;
     240        }
     241
     242        /* cmd == hlp is locked */
     243       
     244        /*
     245         * TODO:
     246         * The command line must be further analyzed and
     247         * the parameters therefrom must be matched and
     248         * converted to those specified in the cmd info
     249         * structure.
     250         */
     251       
     252        spinlock_unlock(&cmd->lock);
     253        interrupts_restore(ipl);
     254        return cmd;
     255}
     256
     257/** List supported commands.
     258 *
     259 * @param cmd Argument vector.
     260 *
     261 * @return 0 on failure, 1 on success.
     262 */
     263int cmd_help(cmd_arg_t *cmd)
     264{
     265        link_t *cur;
     266        ipl_t ipl;
     267
     268        ipl = interrupts_disable();
     269        spinlock_lock(&cmd_lock);
     270       
     271        for (cur = cmd_head.next; cur != &cmd_head; cur = cur->next) {
     272                cmd_info_t *hlp;
     273               
     274                hlp = list_get_instance(cur, cmd_info_t, link);
     275                spinlock_lock(&hlp->lock);
     276               
     277                printf("%s\t%s\n", hlp->name, hlp->description);
     278
     279                spinlock_unlock(&hlp->lock);
     280        }
     281       
     282        spinlock_unlock(&cmd_lock);     
     283        interrupts_restore(ipl);
     284
     285        return 1;
     286}
  • generic/src/main/kinit.c

    r78c32b4 rff3b3197  
    4242#include <arch/mm/page.h>
    4343#include <mm/vm.h>
     44#include <mm/frame.h>
    4445#include <print.h>
    4546#include <memstr.h>
     47#include <console/console.h>
    4648
    4749#ifdef CONFIG_SMP
     
    5658#endif /* CONFIG_TEST */
    5759
    58 #include <mm/frame.h>
     60
    5961
    6062void kinit(void *arg)
     
    169171#endif /* CONFIG_TEST */
    170172
    171         while (1) {
    172                 thread_sleep(1);
    173                 printf("kinit... ");
     173        if (!stdin) {
     174                while (1) {
     175                        thread_sleep(1);
     176                        printf("kinit... ");
     177                }
    174178        }
    175179
  • generic/src/main/main.c

    r78c32b4 rff3b3197  
    3737#include <proc/task.h>
    3838#include <main/kinit.h>
     39#include <main/kconsole.h>
    3940#include <cpu.h>
    4041#include <align.h>
     
    158159        the_initialize(THE);
    159160       
     161        /*
     162         * kconsole data structures must be initialized very early
     163         * because other subsystems will register their respective
     164         * commands.
     165         */
     166        kconsole_init();
     167       
    160168        arch_pre_mm_init();
    161169        early_heap_init(config.base + hardcoded_ktext_size + hardcoded_kdata_size, heap_size + heap_delta);
Note: See TracChangeset for help on using the changeset viewer.