* netboot and memory problem : solved ?
@ 2005-06-17 23:52 Vincent Guffens
2005-06-18 13:51 ` Ext2fs support bug Serbinenko Vladimir
0 siblings, 1 reply; 8+ messages in thread
From: Vincent Guffens @ 2005-06-17 23:52 UTC (permalink / raw)
To: The development of GRUB 2
hi !
what do you think about the following change in grub_free ?
Instead of (at the end of the function)
if (p + p->size == p->next)
{
p->next->magic = 0;
p->size += p->next->size;
p->next = p->next->next;
}
[...]
r->first = q;
I tried the following
if (p + p->size == p->next)
{
p->next->magic = 0;
p->size += p->next->size;
p->next = p->next->next;
r->first = p;
return;
}
as a reminder, my problem was that sometimes, grub2 would fataly print
(error message from grub_free):
free magic is broken at 0x37e50: 0x0
I'm quite sure that my problem is linked with that region of the code,
but I'm not too sure about the consequences of that possible fix.
At least, I can't repoduce the problem on my pc but I'll do some more
testing on monday as this problem is kind of "volatile".
I hope it's the one ! Have a good week-end !
--
Vincent Guffens
PhD Student UCL/CESAME
tel: +32 10 47 80 30
Value your freedom, or you will lose it, teaches history.
"Don't bother us with politics," respond those who don't want to learn.
-- Richard M. Stallman
^ permalink raw reply [flat|nested] 8+ messages in thread
* Ext2fs support bug
2005-06-17 23:52 netboot and memory problem : solved ? Vincent Guffens
@ 2005-06-18 13:51 ` Serbinenko Vladimir
2005-07-13 16:42 ` Marco Gerards
0 siblings, 1 reply; 8+ messages in thread
From: Serbinenko Vladimir @ 2005-06-18 13:51 UTC (permalink / raw)
To: The development of GRUB 2
I create grub image like:
I have: /home/vova/grub/mnt is a mount point of /home/vova/grub/grub.img
$prefix=/home/vova/grub/inst
I run:
from $prefix/sbin:
../bin/grub-mkimage -v -o ./core.img chain ext2
mount /home/vova/grub/mnt/
cp ../share/grub/i386-pc/* ../../mnt/boot/grub/
cp ./core.img ../../mnt/boot/grub
umount /home/vova/grub/mnt/
mount /home/vova/grub/mnt/
sync && ./grub-setup -m ./device.map --root-device=\(fd0\) \(fd0\) -d
/home/vova/grub/mnt/boot/grub/ && sync
umount /home/vova/grub/mnt
And from /home/vova/grub:
qemu -fda ./grub.img
And I recieve:
Welcome to GRUB
unaligned pointer 0x7fef8
When I reformat my image file like fat and replace ext2 with fat it
works fine so I suppose it's ext2fs bug.
Vladimir
P.S. I use GRUB2 CVS
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Ext2fs support bug
2005-06-18 13:51 ` Ext2fs support bug Serbinenko Vladimir
@ 2005-07-13 16:42 ` Marco Gerards
2005-07-30 13:20 ` Bug-fixing and keystroke Serbinenko Vladimir
0 siblings, 1 reply; 8+ messages in thread
From: Marco Gerards @ 2005-07-13 16:42 UTC (permalink / raw)
To: The development of GRUB 2
Serbinenko Vladimir <serbinenko.vova@list.ru> writes:
> And from /home/vova/grub:
> qemu -fda ./grub.img
> And I recieve:
> Welcome to GRUB
>
> unaligned pointer 0x7fef8
>
> When I reformat my image file like fat and replace ext2 with fat it
> works fine so I suppose it's ext2fs bug.
There was a bug in mm.c, perhaps it was related. Can you check if
this was the problem by trying with current CVS? Otherwise, please
send me the floppy image.
Thanks,
Marco
^ permalink raw reply [flat|nested] 8+ messages in thread
* Bug-fixing and keystroke
2005-07-13 16:42 ` Marco Gerards
@ 2005-07-30 13:20 ` Serbinenko Vladimir
2005-07-31 16:19 ` Yoshinori K. Okuji
0 siblings, 1 reply; 8+ messages in thread
From: Serbinenko Vladimir @ 2005-07-30 13:20 UTC (permalink / raw)
To: The development of GRUB 2
[-- Attachment #1: Type: text/plain, Size: 1599 bytes --]
I wrote some bugfixing patch + new feature.
Bug-fixing was mainly about FAT bug (unalloc magic on not-fat fs).
The new feature is sending keystroke to OS (imitating keypress +
changing keyboard flags).
it works like:
keystroke [flags] [keys]
[flags] are like
--capslock=0 --rshift=1 ... (documentation in patch in keystroke.c at
the end)
0 - means set flag to 0, 1 to 1 and 2 means keep value.
Some flags are the modes (like caps, num, scroll). Others are keys (like
ctrl and shift)
If you set 0/1 to mode it will result like turning off/on the mode
If you set key to 1 it will imitate keypressing until you really press it
[keys] are key1 key2 ... like
h e l l o or
down down enter.
keylist is taken from GRUB Legacy + some new keys.
Known bugs (can smb help fix them):
LEDs in qemu are not set
help doesn't contain all useful informations.
Serbinenko Vladimir
2005-07-30 Vladimir Serbinenko <serbinenko.vova@list.ru>
Some bugfixes
* commands/ls.c (grub_ls_list_disks): fixed segmentation fault
when fs == 0 or fs->label == 0
(grub_ls_list_files): Added label showing
* kern/disk.c (grub_print_partinfo): fixed segmentation fault when
fs->label == 0
* fs/fat.c (grub_fat_dir): fixed segmentetaion fault by freeing
Keystroke module(pc) and preboots
* commands/boot.c: Added support for preboot functions
* conf/i386.rmk: new module keystroke
* include/grub/normal.h: new headers and types for preboots
* keystroke/keystroke.c: new file
[-- Attachment #2: key+bugfix.patch --]
[-- Type: text/x-patch, Size: 23076 bytes --]
diff -urN grub2um/commands/boot.c grub2m/commands/boot.c
--- grub2um/commands/boot.c 2005-07-25 15:23:26.000000000 +0200
+++ grub2m/commands/boot.c 2005-07-25 16:58:11.000000000 +0200
@@ -23,13 +23,23 @@
#include <grub/arg.h>
#include <grub/misc.h>
#include <grub/loader.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+
+static grub_prebootfn_t *grub_preboots = 0;
+static int grub_preboot_cnt = 0;
static grub_err_t
grub_cmd_boot (struct grub_arg_list *state __attribute__ ((unused)),
int argc, char **args __attribute__ ((unused)))
{
+ int i;
+
if (argc)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "too many arguments");
+
+ for (i = 0; i < grub_preboot_cnt; i++)
+ grub_preboots[i] ();
grub_loader_boot ();
@@ -38,6 +48,46 @@
\f
+grub_err_t
+grub_preboot_add (grub_prebootfn_t fn)
+{
+ grub_prebootfn_t *tmp;
+ tmp = (grub_prebootfn_t *) grub_realloc (grub_preboots, (grub_preboot_cnt + 1) * sizeof(grub_prebootfn_t));
+ if (!tmp)
+ return grub_errno;
+ grub_preboots = tmp;
+ grub_preboots[grub_preboot_cnt] = fn;
+ grub_preboot_cnt++;
+
+ return 0;
+}
+
+\f
+
+grub_err_t
+grub_preboot_remove (grub_prebootfn_t fn)
+{
+ int i;
+ for (i = 0; i < grub_preboot_cnt; i++)
+ if (grub_preboots[i] == fn)
+ break;
+
+ if (i == grub_preboot_cnt)
+ {
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "fn not found");
+ }
+
+ for (; i < grub_preboot_cnt - 1; i++)
+ grub_preboots[i] = grub_preboots[i + 1];
+
+ grub_preboots = (grub_prebootfn_t *) grub_realloc (grub_preboots, (--grub_preboot_cnt) * sizeof(grub_prebootfn_t));
+
+ return 0;
+
+}
+
+\f
+
#ifdef GRUB_UTIL
void
grub_boot_init (void)
diff -urN grub2um/commands/ls.c grub2m/commands/ls.c
--- grub2um/commands/ls.c 2005-07-25 15:23:26.000000000 +0200
+++ grub2m/commands/ls.c 2005-07-30 13:42:04.000000000 +0200
@@ -84,16 +84,18 @@
grub_printf (", Filesystem type %s",
fs ? fs->name : "Unknown");
-
- (fs->label) (dev, &label);
- if (grub_errno == GRUB_ERR_NONE)
+ if (fs && fs->label)
{
- if (label && grub_strlen (label))
- grub_printf (", Label: %s", label);
- grub_free (label);
+ (fs->label) (dev, &label);
+ if (grub_errno == GRUB_ERR_NONE)
+ {
+ if (label && grub_strlen (label))
+ grub_printf (", Label: %s", label);
+ grub_free (label);
+ }
+ else
+ grub_errno = GRUB_ERR_NONE;
}
- else
- grub_errno = GRUB_ERR_NONE;
}
grub_putchar ('\n');
@@ -108,6 +110,7 @@
}
grub_device_close (dev);
+
}
return 0;
@@ -223,6 +226,19 @@
grub_printf ("(%s): Filesystem is %s.\n",
device_name, fs ? fs->name : "unknown");
+ if (fs && fs->label)
+ {
+ char *label;
+ (fs->label) (dev, &label);
+ if (grub_errno == GRUB_ERR_NONE)
+ {
+ if (label && grub_strlen (label))
+ grub_printf (", Label: %s", label);
+ grub_free (label);
+ }
+ else
+ grub_errno = GRUB_ERR_NONE;
+ }
}
else if (fs)
{
@@ -267,6 +283,7 @@
}
fail:
+
if (dev)
grub_device_close (dev);
diff -urN grub2um/conf/i386-pc.mk grub2m/conf/i386-pc.mk
--- grub2um/conf/i386-pc.mk 2005-07-25 15:23:26.000000000 +0200
+++ grub2m/conf/i386-pc.mk 2005-07-25 15:25:29.000000000 +0200
@@ -989,7 +989,7 @@
font.mod _multiboot.mod ls.mod boot.mod cmp.mod cat.mod \
terminal.mod fshelp.mod chain.mod multiboot.mod amiga.mod \
apple.mod pc.mod sun.mod loopback.mod reboot.mod halt.mod \
- help.mod default.mod timeout.mod configfile.mod
+ help.mod default.mod timeout.mod configfile.mod keystroke.mod
# For _chain.mod.
_chain_mod_SOURCES = loader/i386/pc/chainloader.c
@@ -1781,6 +1781,51 @@
hello_mod_CFLAGS = $(COMMON_CFLAGS)
+# For keystroke.mod.
+keystroke_mod_SOURCES = keystroke/keystroke.c
+CLEANFILES += keystroke.mod mod-keystroke.o mod-keystroke.c pre-keystroke.o keystroke_mod-keystroke_keystroke.o def-keystroke.lst und-keystroke.lst
+MOSTLYCLEANFILES += keystroke_mod-keystroke_keystroke.d
+DEFSYMFILES += def-keystroke.lst
+UNDSYMFILES += und-keystroke.lst
+
+keystroke.mod: pre-keystroke.o mod-keystroke.o
+ -rm -f $@
+ $(LD) -r -d -o $@ $^
+ $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -R .note -R .comment $@
+
+pre-keystroke.o: keystroke_mod-keystroke_keystroke.o
+ -rm -f $@
+ $(LD) -r -d -o $@ $^
+
+mod-keystroke.o: mod-keystroke.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) $(keystroke_mod_CFLAGS) -c -o $@ $<
+
+mod-keystroke.c: moddep.lst genmodsrc.sh
+ sh $(srcdir)/genmodsrc.sh 'keystroke' $< > $@ || (rm -f $@; exit 1)
+
+def-keystroke.lst: pre-keystroke.o
+ $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 keystroke/' > $@
+
+und-keystroke.lst: pre-keystroke.o
+ echo 'keystroke' > $@
+ $(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+keystroke_mod-keystroke_keystroke.o: keystroke/keystroke.c
+ $(CC) -Ikeystroke -I$(srcdir)/keystroke $(CPPFLAGS) $(CFLAGS) $(keystroke_mod_CFLAGS) -c -o $@ $<
+
+keystroke_mod-keystroke_keystroke.d: keystroke/keystroke.c
+ set -e; $(CC) -Ikeystroke -I$(srcdir)/keystroke $(CPPFLAGS) $(CFLAGS) $(keystroke_mod_CFLAGS) -M $< | sed 's,keystroke\.o[ :]*,keystroke_mod-keystroke_keystroke.o $@ : ,g' > $@; [ -s $@ ] || rm -f $@
+
+-include keystroke_mod-keystroke_keystroke.d
+
+CLEANFILES += cmd-keystroke.lst
+COMMANDFILES += cmd-keystroke.lst
+
+cmd-keystroke.lst: keystroke/keystroke.c gencmdlist.sh
+ set -e; $(CC) -Ikeystroke -I$(srcdir)/keystroke $(CPPFLAGS) $(CFLAGS) $(keystroke_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh keystroke > $@ || (rm -f $@; exit 1)
+
+keystroke_mod_CFLAGS = $(COMMON_CFLAGS)
+
# For boot.mod.
boot_mod_SOURCES = commands/boot.c
CLEANFILES += boot.mod mod-boot.o mod-boot.c pre-boot.o boot_mod-commands_boot.o def-boot.lst und-boot.lst
diff -urN grub2um/conf/i386-pc.rmk grub2m/conf/i386-pc.rmk
--- grub2um/conf/i386-pc.rmk 2005-07-25 15:23:26.000000000 +0200
+++ grub2m/conf/i386-pc.rmk 2005-07-25 15:25:29.000000000 +0200
@@ -102,7 +102,7 @@
font.mod _multiboot.mod ls.mod boot.mod cmp.mod cat.mod \
terminal.mod fshelp.mod chain.mod multiboot.mod amiga.mod \
apple.mod pc.mod sun.mod loopback.mod reboot.mod halt.mod \
- help.mod default.mod timeout.mod configfile.mod
+ help.mod default.mod timeout.mod configfile.mod keystroke.mod
# For _chain.mod.
_chain_mod_SOURCES = loader/i386/pc/chainloader.c
@@ -163,6 +163,10 @@
hello_mod_SOURCES = hello/hello.c
hello_mod_CFLAGS = $(COMMON_CFLAGS)
+# For keystroke.mod.
+keystroke_mod_SOURCES = keystroke/keystroke.c
+keystroke_mod_CFLAGS = $(COMMON_CFLAGS)
+
# For boot.mod.
boot_mod_SOURCES = commands/boot.c
boot_mod_CFLAGS = $(COMMON_CFLAGS)
diff -urN grub2um/fs/fat.c grub2m/fs/fat.c
--- grub2um/fs/fat.c 2005-07-25 15:23:26.000000000 +0200
+++ grub2m/fs/fat.c 2005-07-30 14:26:32.000000000 +0200
@@ -629,7 +629,7 @@
struct grub_fat_data *data = 0;
grub_disk_t disk = device->disk;
grub_size_t len;
- char *dirname;
+ char *dirname = 0;
char *p;
#ifndef GRUB_UTIL
@@ -660,8 +660,10 @@
fail:
- grub_free (dirname);
- grub_free (data);
+ if (dirname)
+ grub_free (dirname);
+ if (data)
+ grub_free (data);
#ifndef GRUB_UTIL
grub_dl_unref (my_mod);
diff -urN grub2um/include/grub/normal.h grub2m/include/grub/normal.h
--- grub2um/include/grub/normal.h 2005-07-25 15:23:26.000000000 +0200
+++ grub2m/include/grub/normal.h 2005-07-25 15:25:29.000000000 +0200
@@ -44,6 +44,9 @@
/* Not loaded yet. Used for auto-loading. */
#define GRUB_COMMAND_FLAG_NOT_LOADED 0x20
+/* Preboot function declaration. */
+typedef void (*grub_prebootfn_t) (void);
+
/* The command description. */
struct grub_command
{
@@ -178,6 +181,8 @@
grub_menu_t grub_context_get_current_menu (void);
grub_menu_t grub_context_push_menu (grub_menu_t menu);
void grub_context_pop_menu (void);
+grub_err_t grub_preboot_add (grub_prebootfn_t fn);
+grub_err_t grub_preboot_remove (grub_prebootfn_t fn);
#ifdef GRUB_UTIL
void grub_normal_init (void);
diff -urN grub2um/kern/disk.c grub2m/kern/disk.c
--- grub2um/kern/disk.c 2005-07-25 15:23:26.000000000 +0200
+++ grub2m/kern/disk.c 2005-07-30 12:14:34.000000000 +0200
@@ -535,7 +535,7 @@
grub_printf ("\tPartition num:%s, Filesystem type %s",
partname, fs ? fs->name : "Unknown");
- if (fs)
+ if (fs && fs->label)
{
(fs->label) (part, &label);
if (grub_errno == GRUB_ERR_NONE)
diff -urN grub2um/keystroke/keystroke.c grub2m/keystroke/keystroke.c
--- grub2um/keystroke/keystroke.c 1970-01-01 01:00:00.000000000 +0100
+++ grub2m/keystroke/keystroke.c 2005-07-28 16:59:19.000000000 +0200
@@ -0,0 +1,406 @@
+/* keystroke.c - test module for dynamic loading */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2005 Free Software Foundation, Inc.
+ * Copyright (C) 2005 Vladimir Serbinenko serbinenko.vova@bk.ru
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <grub/types.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/dl.h>
+#include <grub/normal.h>
+#include <grub/arg.h>
+
+#define RAW_ADDR(a) ((void *)(a))
+struct
+keysym
+{
+ char *unshifted_name; /* the name in unshifted state */
+ char *shifted_name; /* the name in shifted state */
+ unsigned char unshifted_ascii; /* the ascii code in unshifted state */
+ unsigned char shifted_ascii; /* the ascii code in shifted state */
+ unsigned char keycode; /* keyboard scancode */
+};
+
+char keystroke[32];
+int keylen=0;
+/* The sum of:
+ x << y x - action y - flag
+ x: 0x0 - turn off, 0x1 - turn on , 0x3 - keep
+ y:
+ 0x0 - numlock mode,
+ 0x1 - capslock mode,
+ 0x2 - scrolllock mode,
+ 0x3 - insert mode,
+ 0x4 - wait mode,
+ 0x5 - left shift key,
+ 0x6 - right shift key,
+ 0x7 - left alt key,
+ 0x8 - right alt key,
+ 0x9 - left ctrl key,
+ 0xa - right ctrl key,
+ 0xb - sysreq key,
+ 0xc - numlock key,
+ 0xd - capslock key,
+ 0xe - scrolllock key,
+ 0xf - insert key
+ */
+unsigned long kbflags=0;
+int noled = 1;
+
+/* The table for key symbols. If the "shifted" member of an entry is
+ NULL, the entry does not have shifted state. Copied from GRUB Legacy setkey fuction */
+static struct keysym keysym_table[] =
+{
+ {"escape", 0, 0x1b, 0, 0x01},
+ {"1", "exclam", '1', '!', 0x02},
+ {"2", "at", '2', '@', 0x03},
+ {"3", "numbersign", '3', '#', 0x04},
+ {"4", "dollar", '4', '$', 0x05},
+ {"5", "percent", '5', '%', 0x06},
+ {"6", "caret", '6', '^', 0x07},
+ {"7", "ampersand", '7', '&', 0x08},
+ {"8", "asterisk", '8', '*', 0x09},
+ {"9", "parenleft", '9', '(', 0x0a},
+ {"0", "parenright", '0', ')', 0x0b},
+ {"minus", "underscore", '-', '_', 0x0c},
+ {"equal", "plus", '=', '+', 0x0d},
+ {"backspace", 0, '\b', 0, 0x0e},
+ {"tab", 0, '\t', 0, 0x0f},
+ {"q", "Q", 'q', 'Q', 0x10},
+ {"w", "W", 'w', 'W', 0x11},
+ {"e", "E", 'e', 'E', 0x12},
+ {"r", "R", 'r', 'R', 0x13},
+ {"t", "T", 't', 'T', 0x14},
+ {"y", "Y", 'y', 'Y', 0x15},
+ {"u", "U", 'u', 'U', 0x16},
+ {"i", "I", 'i', 'I', 0x17},
+ {"o", "O", 'o', 'O', 0x18},
+ {"p", "P", 'p', 'P', 0x19},
+ {"bracketleft", "braceleft", '[', '{', 0x1a},
+ {"bracketright", "braceright", ']', '}', 0x1b},
+ {"enter", 0, '\r', 0, 0x1c},
+ {"control", 0, 0, 0, 0x1d},
+ {"a", "A", 'a', 'A', 0x1e},
+ {"s", "S", 's', 'S', 0x1f},
+ {"d", "D", 'd', 'D', 0x20},
+ {"f", "F", 'f', 'F', 0x21},
+ {"g", "G", 'g', 'G', 0x22},
+ {"h", "H", 'h', 'H', 0x23},
+ {"j", "J", 'j', 'J', 0x24},
+ {"k", "K", 'k', 'K', 0x25},
+ {"l", "L", 'l', 'L', 0x26},
+ {"semicolon", "colon", ';', ':', 0x27},
+ {"quote", "doublequote", '\'', '"', 0x28},
+ {"backquote", "tilde", '`', '~', 0x29},
+ {"shift", 0, 0, 0, 0x2a},
+ {"backslash", "bar", '\\', '|', 0x2b},
+ {"z", "Z", 'z', 'Z', 0x2c},
+ {"x", "X", 'x', 'X', 0x2d},
+ {"c", "C", 'c', 'C', 0x2e},
+ {"v", "V", 'v', 'V', 0x2f},
+ {"b", "B", 'b', 'B', 0x30},
+ {"n", "N", 'n', 'N', 0x31},
+ {"m", "M", 'm', 'M', 0x32},
+ {"comma", "less", ',', '<', 0x33},
+ {"period", "greater", '.', '>', 0x34},
+ {"slash", "question", '/', '?', 0x35},
+ {"rshift", 0, 0, 0, 0x36},
+ {"numasterisk", 0, '*', 0, 0x37},
+ {"alt", 0, 0, 0, 0x38},
+ {"space", 0, ' ', 0, 0x39},
+ {"capslock", 0, 0, 0, 0x3a},
+ {"F1", 0, 0, 0, 0x3b},
+ {"F2", 0, 0, 0, 0x3c},
+ {"F3", 0, 0, 0, 0x3d},
+ {"F4", 0, 0, 0, 0x3e},
+ {"F5", 0, 0, 0, 0x3f},
+ {"F6", 0, 0, 0, 0x40},
+ {"F7", 0, 0, 0, 0x41},
+ {"F8", 0, 0, 0, 0x42},
+ {"F9", 0, 0, 0, 0x43},
+ {"F10", 0, 0, 0, 0x44},
+ {"num7", "numhome", '7', 0, 0x47},
+ {"num8", "numup", '8', 0, 0x48},
+ {"num9", "numpgup", '9', 0, 0x49},
+ {"numminus", 0, '-', 0, 0x4a},
+ {"num4", "numleft", '4', 0, 0x4b},
+ {"num5", "num5numlock", '5', 0, 0x4c},
+ {"num6", "numright", '6', 0, 0x4d},
+ {"numplus", 0, '-', 0, 0x4e},
+ {"num1", "numend", '1', 0, 0x4f},
+ {"num2", "numdown", '2', 0, 0x50},
+ {"num3", "numpgdown", '3', 0, 0x51},
+ {"num0", "numinsert", '0', 0, 0x52},
+ {"numperiod", "numdelete", 0, 0x7f, 0x53},
+ {"F11", 0, 0, 0, 0x57},
+ {"F12", 0, 0, 0, 0x58},
+ {"numenter", 0, '\r', 0, 0xe0},
+ {"numslash", 0, '/', 0, 0xe0},
+ {"delete", 0, 0x7f, 0, 0xe0},
+ {"insert", 0, 0xe0, 0, 0x52},
+ {"home", 0, 0xe0, 0, 0x47},
+ {"end", 0, 0xe0, 0, 0x4f},
+ {"pgdown", 0, 0xe0, 0, 0x51},
+ {"pgup", 0, 0xe0, 0, 0x49},
+ {"down", 0, 0xe0, 0, 0x50},
+ {"up", 0, 0xe0, 0, 0x48},
+ {"left", 0, 0xe0, 0, 0x4b},
+ {"right", 0, 0xe0, 0, 0x4d}
+};
+
+/* Send a character VALUE to port PORT */
+static void
+outportb (char value, int port) {
+ asm volatile ("outb %%al,%%dx": :"a" (value),"d" (port));
+ return;
+}
+
+/* Read a byte from port PORT */
+static unsigned char
+inb (unsigned int port)
+{
+ unsigned char ret;
+ asm volatile ("inb %%dx,%%al":"=a" (ret):"d" (port));
+ return ret;
+
+}
+
+/* Set a simple flag in flags variable
+ flags - where to set,
+ outoffset - offset of flag in FLAGS,
+ inoffset - offset of flag in kbflags
+*/
+static void
+grub_keystroke_set_simple_flag (unsigned long *flags, int outoffset, int inoffset)
+{
+ /* previous state of flag */
+ int prevstat = (*flags >> outoffset) & 1;
+ /* what to do with flag*/
+ int operation = (kbflags >> inoffset) & 3;
+ /* new state */
+ int newstat = (operation == 1) || (operation == 2 && prevstat);
+ /* Set new state */
+ *flags = (*flags & (~(1 << outoffset))) | (newstat << outoffset);
+}
+
+/* Set a double flag (ctrl/alt) in flags variable
+ flags - where to set,
+ outoffsetc - offset of common flag in FLAGS,
+ outoffsetl - offset of "left" flag in FLAGS,
+ inoffsetr - offset of "right" flag in kbflags,
+ inoffsetl - offset of "left" flag in kbflags,
+*/
+static void
+grub_keystroke_set_double_flag (unsigned long *flags, int outoffsetc, int outoffsetl, int inoffsetr, int inoffsetl)
+{
+ /* previous state of flag */
+ int prevstatc = (*flags >> outoffsetc) & 1;
+ int prevstatl = (*flags >> outoffsetl) & 1;
+ int prevstatr = prevstatc && (!prevstatl);
+ /* what to do with flag*/
+ int operationr = (kbflags >> inoffsetr) & 3;
+ int operationl = (kbflags >> inoffsetl) & 3;
+ /* new state */
+ int newstatl = (operationl == 1) || (operationl == 2 && prevstatl);
+ int newstatr = (operationr == 1) || (operationr == 2 && prevstatr);
+ int newstatc = newstatr || newstatr;
+ /* Set new state */
+ *flags = (*flags & (~(1 << outoffsetl))) | (newstatl << outoffsetl);
+ *flags = (*flags & (~(1 << outoffsetc))) | (newstatc << outoffsetc);
+}
+
+
+/* Set keyboard buffer to our keystroke */
+static void
+grub_keystroke_preboot (void)
+{
+
+ int i;
+ /* For convenion: pointer to flags */
+ unsigned long *flags = (unsigned long *) RAW_ADDR (0x417);
+
+ /* Set the keystroke */
+ *((char *) RAW_ADDR (0x41a)) = 0x1e;
+ *((char *) RAW_ADDR (0x41c)) = keylen+0x1e;
+ for(i = 0; i < 0x20; i++)
+ ((char *) RAW_ADDR (0x41e))[i] = keystroke[i];
+
+ /* Set the flags. For more information reffer to technical specification*/
+ grub_keystroke_set_simple_flag (flags, 5, 0 * 2); // numlock mode
+ grub_keystroke_set_simple_flag (flags, 6, 1 * 2); // capslock mode
+ grub_keystroke_set_simple_flag (flags, 4, 2 * 2); // scrolllock mode
+ grub_keystroke_set_simple_flag (flags, 7, 3 * 2); // insert mode
+ grub_keystroke_set_simple_flag (flags, 11, 4 * 2); // wait mode
+ grub_keystroke_set_simple_flag (flags, 1, 5 * 2); // left shift
+ grub_keystroke_set_simple_flag (flags, 0, 6 * 2); // right shift
+ grub_keystroke_set_simple_flag (flags, 10, 0xb * 2); // sysreq
+ grub_keystroke_set_simple_flag (flags, 13, 0xc * 2); // numlock key
+ grub_keystroke_set_simple_flag (flags, 14, 0xd * 2); // capslock key
+ grub_keystroke_set_simple_flag (flags, 12, 0xe * 2); // scrolllock key
+ grub_keystroke_set_simple_flag (flags, 15, 0xf * 2); // insert key
+
+ /*Set ctrl and alt*/
+ grub_keystroke_set_double_flag (flags, 2, 8, 0xa * 2, 9 * 2); //Ctrl
+ grub_keystroke_set_double_flag (flags, 3, 9, 8 * 2, 7 * 2); //Alt
+
+ /* Write new LED state */
+ if (!noled)
+ {
+ int value = 0;
+ int failed;
+ /* Try 5 times */
+ for (failed = 0; failed < 5; failed++)
+ {
+ value = 0;
+ /* Send command change LEDs */
+ outportb (0xed, 0x60);
+
+ /* Wait */
+ while ((value != 0xfa) && (value != 0xfe))
+ value = inb (0x60);
+
+ if (value == 0xfa)
+ {
+ /* Set new LEDs*/
+ outportb ((flags[0] >> 4) & 7, 0x60);
+ break;
+ }
+ }
+ }
+}
+
+ /* 0x0 - numlock mode,
+ 0x1 - capslock mode,
+ 0x2 - scrolllock mode,
+ 0x3 - insert mode,
+ 0x4 - wait mode,
+ 0x5 - left shift key,
+ 0x6 - right shift key,
+ 0x7 - left alt key,
+ 0x8 - right alt key,
+ 0x9 - left ctrl key,
+ 0xa - right ctrl key,
+ 0xb - sysreq key,
+ 0xc - numlock key,
+ 0xd - capslock key,
+ 0xe - scrolllock key,
+ 0xf - insert key*/
+
+/*Parse keystroke */
+static grub_err_t
+grub_cmd_keystroke (struct grub_arg_list *state,
+ int argc,
+ char **args)
+{
+
+ /* To stop warning */
+ auto int find_key_code (char *key);
+ auto int find_ascii_code (char *key);
+
+ auto int find_key_code (char *key)
+ {
+ unsigned i;
+
+ for (i = 0; i < sizeof (keysym_table) / sizeof (keysym_table[0]); i++)
+ {
+ if (keysym_table[i].unshifted_name && grub_strcmp (key, keysym_table[i].unshifted_name) == 0)
+ return keysym_table[i].keycode;
+ else if (keysym_table[i].shifted_name && grub_strcmp (key, keysym_table[i].shifted_name) == 0)
+ return keysym_table[i].keycode;
+ }
+
+ return 0;
+ }
+
+ auto int find_ascii_code (char *key)
+ {
+ unsigned i;
+
+ for (i = 0; i < sizeof (keysym_table) / sizeof (keysym_table[0]); i++)
+ {
+ if (keysym_table[i].unshifted_name && grub_strcmp (key, keysym_table[i].unshifted_name) == 0)
+ return keysym_table[i].unshifted_ascii;
+ else if (keysym_table[i].shifted_name && grub_strcmp (key, keysym_table[i].shifted_name) == 0)
+ return keysym_table[i].shifted_ascii;
+ }
+
+ return 0;
+ }
+
+ int i;
+
+ /* Set keystroke and keylen variables*/
+ keylen = 0;
+
+ for (i = 0; i < argc && keylen < 0x20; i++)
+ {
+ if (find_key_code (args[i]))
+ {
+ keystroke[keylen++] = find_ascii_code (args[i]);
+ keystroke[keylen++] = find_key_code (args[i]);
+ }
+ }
+
+ /* Set kbflags */
+ kbflags = 0;
+ for (i = 0; i <= 15; i++)
+ kbflags |= (state[i].set ? grub_strtoul (state[i].arg, 0, 0) : 2) << (2*i);
+
+ noled = state[16].set;
+
+ return 0;
+}
+
+static const struct grub_arg_option options[] =
+ {
+ {"numlock", 'n', GRUB_ARG_OPTION_OPTIONAL, "set numlock mode (2=keep, 0=off, 1=on)", "2", ARG_TYPE_INT},
+ {"capslock", 'c', GRUB_ARG_OPTION_OPTIONAL, "set capslock mode (2=keep, 0=off, 1=on)", "2", ARG_TYPE_INT},
+ {"scrolllock", 's', GRUB_ARG_OPTION_OPTIONAL, "set scrolllock mode (2=keep, 0=off, 1=on)", "2", ARG_TYPE_INT},
+ {"insert", 'i', GRUB_ARG_OPTION_OPTIONAL, "set insert mode (2=keep, 0=off, 1=on)", "2", ARG_TYPE_INT},
+ {"wait", 0 , GRUB_ARG_OPTION_OPTIONAL, "set wait mode (pause) (2=keep, 0=off, 1=on)", "2", ARG_TYPE_INT},
+ {"lshift", 'l', GRUB_ARG_OPTION_OPTIONAL, "block left shift key (2=no, 0=unpress, 1=press)", "2", ARG_TYPE_INT},
+ {"rshift", 'r', GRUB_ARG_OPTION_OPTIONAL, "block right shift key (2=no, 0=unpress, 1=press)", "2", ARG_TYPE_INT},
+ {"lalt", 0 , GRUB_ARG_OPTION_OPTIONAL, "block left alt key (2=no, 0=unpress, 1=press)", "2", ARG_TYPE_INT},
+ {"ralt", 'a', GRUB_ARG_OPTION_OPTIONAL, "block right alt key (2=no, 0=unpress, 1=press)", "2", ARG_TYPE_INT},
+ {"lctrl", 0 , GRUB_ARG_OPTION_OPTIONAL, "block left ctrl key (2=no, 0=unpress, 1=press)", "2", ARG_TYPE_INT},
+ {"rctrl", 0 , GRUB_ARG_OPTION_OPTIONAL, "block right ctrl key (2=no, 0=unpress, 1=press)", "2", ARG_TYPE_INT},
+ {"sysreq", 0 , GRUB_ARG_OPTION_OPTIONAL, "block sys req key (2=no, 0=unpress, 1=press)", "2", ARG_TYPE_INT},
+ {"numkey", 0 , GRUB_ARG_OPTION_OPTIONAL, "block numlock key (2=no, 0=unpress, 1=press)", "2", ARG_TYPE_INT},
+ {"capskey", 0 , GRUB_ARG_OPTION_OPTIONAL, "block capslock key (2=no, 0=unpress, 1=press)", "2", ARG_TYPE_INT},
+ {"scrkey", 0 , GRUB_ARG_OPTION_OPTIONAL, "block scrolllock key (2=no, 0=unpress, 1=press)", "2", ARG_TYPE_INT},
+ {"inskey", 0 , GRUB_ARG_OPTION_OPTIONAL, "block insert key (2=no, 0=unpress, 1=press)", "2", ARG_TYPE_INT},
+ {"noled", 0 , 0, "Don't try to set LEDs. Try if blocks.", 0, 0},
+ {0, 0, 0, 0, 0, 0}
+ };
+
+GRUB_MOD_INIT
+{
+ (void)mod; /* To stop warning. */
+ grub_register_command ("keystroke", grub_cmd_keystroke, GRUB_COMMAND_FLAG_BOTH,
+ "keystroke [options] [KEY1 [KEY2 ...[KEY16]...]]",
+"Send a keystroke to OS. Set keyboard mode and block some keys as pressed/unpressed. Keys are unblocked on next press.", options);
+ grub_preboot_add (grub_keystroke_preboot);
+}
+
+GRUB_MOD_FINI
+{
+ grub_unregister_command ("keystroke");
+ grub_preboot_remove (grub_keystroke_preboot);
+}
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Bug-fixing and keystroke
2005-07-30 13:20 ` Bug-fixing and keystroke Serbinenko Vladimir
@ 2005-07-31 16:19 ` Yoshinori K. Okuji
0 siblings, 0 replies; 8+ messages in thread
From: Yoshinori K. Okuji @ 2005-07-31 16:19 UTC (permalink / raw)
To: The development of GRUB 2
On Saturday 30 July 2005 15:20, Serbinenko Vladimir wrote:
> I wrote some bugfixing patch + new feature.
Thank you very much. I have applied only the bugfixes at the moment.
> The new feature is sending keystroke to OS (imitating keypress +
> changing keyboard flags).
> it works like:
> keystroke [flags] [keys]
This is specific to i386-pc, so the source file should be put in
commands/i386/pc.
I'm also wondering if this command name is good or not. In QEMU, the same
feature is called "sendkey". I'm not sure which is better.
Another question I have is that it might be better to implement this as a
variable rather than a command. Basically, this command just stores
information rathen than executing something directly. So using a variable
sounds intuitive for me.
What do you think?
Okuji
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Bug-fixing and keystroke
@ 2005-08-01 10:11 Serbinenko Vladimir
2005-08-01 10:58 ` Marco Gerards
0 siblings, 1 reply; 8+ messages in thread
From: Serbinenko Vladimir @ 2005-08-01 10:11 UTC (permalink / raw)
To: The development of GRUB 2
>On Saturday 30 July 2005 15:20, Serbinenko Vladimir wrote:
>>/ I wrote some bugfixing patch + new feature./
>
>Thank you very much. I have applied only the bugfixes at the moment.
>
OK
>>/ The new feature is sending keystroke to OS (imitating keypress +/
>>/ changing keyboard flags)./
>>/ it works like:/
>>/ keystroke [flags] [keys]/
>
>This is specific to i386-pc, so the source file should be put in
>commands/i386/pc.
Fixed
>I'm also wondering if this command name is good or not. In QEMU, the same
>feature is called "sendkey". I'm not sure which is better.
For me it makes no difference but if other apps use "sendkey" it would be better make standardly
>Another question I have is that it might be better to implement this as a
>variable rather than a command. Basically, this command just stores
>information rathen than executing something directly. So using a variable
>sounds intuitive for me.
>
>What do you think?
>
I propose one "sendkey" variable and bunch of kb_* variables like kb_caps, kb_scroll, kb_rshift, kb_noleds ...
Is it OK?
Then 2 questions arise:
1) Which values would be intuitive for kb_*?What about keep, on, off?
2) How can user call the help? Especially how can user know the available keys? Perhaps this question is more
general and we have to extend "help" command?
>Okuji
>
Vladimir Serbinenko
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Bug-fixing and keystroke
2005-08-01 10:11 Serbinenko Vladimir
@ 2005-08-01 10:58 ` Marco Gerards
0 siblings, 0 replies; 8+ messages in thread
From: Marco Gerards @ 2005-08-01 10:58 UTC (permalink / raw)
To: The development of GRUB 2
Serbinenko Vladimir <serbinenko.vova@list.ru> writes:
> 2) How can user call the help? Especially how can user know the
> available keys? Perhaps this question is more general and we have to
> extend "help" command?
How about something like `sendkeys --list-keys'. Does that make
sense?
--
Marco
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Bug-fixing and keystroke
@ 2005-08-02 12:16 Vladimir Serbinenko
0 siblings, 0 replies; 8+ messages in thread
From: Vladimir Serbinenko @ 2005-08-02 12:16 UTC (permalink / raw)
To: The development of GRUB 2
>
>
>Serbinenko Vladimir <address@hidden> writes:
>
>>/ 2) How can user call the help? Especially how can user know the/
>>/ available keys? Perhaps this question is more general and we have to/
>>/ extend "help" command?/
>
>How about something like `sendkeys --list-keys'. Does that make
>sense?
>
>
>
The problem is that sendkey is a variable. So we have no command.
I could also write a command but does it make sense to have command and
a variable?
The same problem we have with pager and root variables but while root is
set form the
beginning and quite intuitive, pager is intuitive but at the beginning
you don't see it so you
have to know that it exists but sendkey and kb_* are not very intuitive
and set only when
you load sendkey module.
Vladimir
P. S. I've just written the "hide", "unhide" and "parttype" commands.
Will send a patch after testing
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2005-08-02 12:21 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-06-17 23:52 netboot and memory problem : solved ? Vincent Guffens
2005-06-18 13:51 ` Ext2fs support bug Serbinenko Vladimir
2005-07-13 16:42 ` Marco Gerards
2005-07-30 13:20 ` Bug-fixing and keystroke Serbinenko Vladimir
2005-07-31 16:19 ` Yoshinori K. Okuji
-- strict thread matches above, loose matches on Subject: below --
2005-08-01 10:11 Serbinenko Vladimir
2005-08-01 10:58 ` Marco Gerards
2005-08-02 12:16 Vladimir Serbinenko
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.