Author: stepan
Date: 2008-10-22 13:19:52 +0200 (Wed, 22 Oct 2008)
New Revision: 83
Modified:
trunk/filo/Config.in
trunk/filo/Makefile
trunk/filo/build.sh
trunk/filo/configs/defconfig
trunk/filo/drivers/ide.c
trunk/filo/drivers/newusb/usb.c
trunk/filo/fs/blockdev.c
trunk/filo/fs/fsys_ext2fs.c
trunk/filo/include/grub/shared.h
trunk/filo/main/filo.c
trunk/filo/main/grub/builtins.c
trunk/filo/main/grub/char_io.c
trunk/filo/main/grub/cmdline.c
trunk/filo/main/grub/grub.c
trunk/filo/util/checksum_elf.c
Log:
New FILO code drop from coresystems' internal repository:
* add "developer commands" to filo (lspci, setpci, io)
* use staged libpayload per default now.
* use libpayload-config.h where appropriate.
* fix an ext3 filesystem issues
* use libpayload functions to implement grub_printf instead of the incomplete
duplication
* fix broken "weak" symbol handling.
* fix string issue with boot_devices
* fix a couple of problems with colors
* fix endless loop in case of file open error
Modified: trunk/filo/Config.in
===================================================================
--- trunk/filo/Config.in 2008-10-18 20:29:55 UTC (rev 82)
+++ trunk/filo/Config.in 2008-10-22 11:19:52 UTC (rev 83)
@@ -330,5 +330,13 @@
depends on ARTEC_BOOT
default n
+config DEVELOPER_TOOLS
+ bool "Developer Tools"
+ depends on USE_GRUB
+ default y
+ help
+ Add commands useful for hardware development to the GRUB
+ interface. These are lspci, setpci, io.
+
endmenu
Modified: trunk/filo/Makefile
===================================================================
--- trunk/filo/Makefile 2008-10-18 20:29:55 UTC (rev 82)
+++ trunk/filo/Makefile 2008-10-22 11:19:52 UTC (rev 83)
@@ -70,7 +70,7 @@
include $(PLATFORM-y) $(BUILD-y)
-LIBPAYLOAD_PREFIX ?= libpayload
+LIBPAYLOAD_PREFIX ?= $(obj)/libpayload
LIBPAYLOAD = $(LIBPAYLOAD_PREFIX)/lib/libpayload.a
INCPAYLOAD = $(LIBPAYLOAD_PREFIX)/include
LIBGCC = $(shell $(CC) $(CFLAGS) -print-libgcc-file-name)
Modified: trunk/filo/build.sh
===================================================================
--- trunk/filo/build.sh 2008-10-18 20:29:55 UTC (rev 82)
+++ trunk/filo/build.sh 2008-10-22 11:19:52 UTC (rev 83)
@@ -1,11 +1,16 @@
-#!/bin/sh
+#!/bin/bash
CONFIG=defconfig
-ALLCLEAN=1
+for make in make gmake gnumake; do
+ if [ "`$make --version 2>/dev/null | grep -c GNU`" -gt 0 ]; then
+ MAKE=$make
+ break
+ fi
+done
OS=`uname -s`
-if [ "$OS" == "Darwin" -o "${OS:0:6}" == "CYGWIN" ]; then
+if [ "$OS" = "Darwin" -o "$OS" = "SunOS" -o "${OS:0:6}" = "CYGWIN" ]; then
MAKEFLAGS=" \
AS=i386-elf-as \
CC=i386-elf-gcc \
@@ -17,21 +22,21 @@
-j \
"
fi
-if [ "$OS" == "Linux" ]; then
-MAKEFLAGS='CC="gcc -m32" LD="ld -b elf32-i386" HOSTCC="gcc" AS="as --32"'
+if [ "$OS" = "Linux" ]; then
+ MAKEFLAGS='CC="gcc -m32" LD="ld -b elf32-i386" HOSTCC="gcc" AS="as --32"'
fi
-if [ "$ALLCLEAN" != "" -o ! -r libpayload/build/lib/libpayload.a ]; then
- cd libpayload
- cp configs/$CONFIG .config
- make clean
- make oldconfig
- eval make $MAKEFLAGS
- cd ..
-fi
-
-make distclean
+$MAKE distclean
cp configs/$CONFIG ./.config
-make oldconfig
-eval make $MAKEFLAGS
+$MAKE oldconfig
+cd libpayload
+$MAKE distclean
+cp configs/$CONFIG .config
+$MAKE oldconfig
+eval $MAKE $MAKEFLAGS
+eval $MAKE $MAKEFLAGS DESTDIR=../build install
+cd ..
+
+eval $MAKE $MAKEFLAGS
+
Modified: trunk/filo/configs/defconfig
===================================================================
--- trunk/filo/configs/defconfig 2008-10-18 20:29:55 UTC (rev 82)
+++ trunk/filo/configs/defconfig 2008-10-22 11:19:52 UTC (rev 83)
@@ -66,3 +66,4 @@
# CONFIG_DEBUG_LINUXLOAD is not set
# CONFIG_DEBUG_IDE is not set
# CONFIG_DEBUG_ELTORITO is not set
+CONFIG_DEVELOPER_TOOLS=y
Modified: trunk/filo/drivers/ide.c
===================================================================
--- trunk/filo/drivers/ide.c 2008-10-18 20:29:55 UTC (rev 82)
+++ trunk/filo/drivers/ide.c 2008-10-22 11:19:52 UTC (rev 83)
@@ -734,7 +734,7 @@
(drive_info[2] != 0x8C73) &&
(drive_info[2] != 0xC837) &&
(drive_info[2] != 0x0000)) {
- printf("Invalid IDE Configuration: %hx\n", drive_info[2]);
+ printf("Invalid IDE Configuration: %04x\n", drive_info[2]);
return 1;
}
for(i = 27; i < 47; i++) {
Modified: trunk/filo/drivers/newusb/usb.c
===================================================================
--- trunk/filo/drivers/newusb/usb.c 2008-10-18 20:29:55 UTC (rev 82)
+++ trunk/filo/drivers/newusb/usb.c 2008-10-22 11:19:52 UTC (rev 83)
@@ -17,6 +17,10 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <libpayload-config.h>
+
+/* Only use this code if libpayload is compiled with USB stack */
+#ifdef CONFIG_USB
#include <fs.h>
#include <usb/usb.h>
#include <usb/usbmsc.h>
@@ -68,3 +72,4 @@
int result = -readwrite_blocks(devs[drive], sector, size, cbw_direction_data_in, buffer);
return result;
}
+#endif
Modified: trunk/filo/fs/blockdev.c
===================================================================
--- trunk/filo/fs/blockdev.c 2008-10-18 20:29:55 UTC (rev 82)
+++ trunk/filo/fs/blockdev.c 2008-10-22 11:19:52 UTC (rev 83)
@@ -19,6 +19,7 @@
*/
#include <libpayload.h>
+#include <libpayload-config.h>
#include <config.h>
#include <fs.h>
@@ -255,7 +256,7 @@
disk_size = (uint32_t) - 1; /* FIXME */
break;
#endif
-#ifdef CONFIG_USB_NEW_DISK
+#if defined(CONFIG_USB_NEW_DISK) && defined(CONFIG_USB)
case DISK_NEW_USB:
if (usb_new_probe(drive) != 0) {
debug("Failed to open USB.\n");
@@ -389,7 +390,7 @@
goto readerr;
break;
#endif
-#ifdef CONFIG_USB_NEW_DISK
+#if defined(CONFIG_USB_NEW_DISK) && defined(CONFIG_USB)
case DISK_NEW_USB:
{
int count = (NUM_CACHE-hash>8)?8:(NUM_CACHE-hash);
Modified: trunk/filo/fs/fsys_ext2fs.c
===================================================================
--- trunk/filo/fs/fsys_ext2fs.c 2008-10-18 20:29:55 UTC (rev 82)
+++ trunk/filo/fs/fsys_ext2fs.c 2008-10-22 11:19:52 UTC (rev 83)
@@ -76,7 +76,50 @@
__u32 s_rev_level; /* Revision level */
__u16 s_def_resuid; /* Default uid for reserved blocks */
__u16 s_def_resgid; /* Default gid for reserved blocks */
- __u32 s_reserved[235]; /* Padding to the end of the block */
+ /*
+ * These fields are for EXT2_DYNAMIC_REV superblocks only.
+ *
+ * Note: the difference between the compatible feature set and
+ * the incompatible feature set is that if there is a bit set
+ * in the incompatible feature set that the kernel doesn't
+ * know about, it should refuse to mount the filesystem.
+ *
+ * e2fsck's requirements are more strict; if it doesn't know
+ * about a feature in either the compatible or incompatible
+ * feature set, it must abort and not try to meddle with
+ * things it doesn't understand...
+ */
+ __u32 s_first_ino; /* First non-reserved inode */
+ __u16 s_inode_size; /* size of inode structure */
+ __u16 s_block_group_nr; /* block group # of this superblock */
+ __u32 s_feature_compat; /* compatible feature set */
+ __u32 s_feature_incompat; /* incompatible feature set */
+ __u32 s_feature_ro_compat; /* readonly-compatible feature set */
+ __u8 s_uuid[16]; /* 128-bit uuid for volume */
+ char s_volume_name[16]; /* volume name */
+ char s_last_mounted[64]; /* directory where last mounted */
+ __u32 s_algorithm_usage_bitmap; /* For compression */
+ /*
+ * Performance hints. Directory preallocation should only
+ * happen if the EXT2_COMPAT_PREALLOC flag is on.
+ */
+ __u8 s_prealloc_blocks; /* Nr of blocks to try to preallocate*/
+ __u8 s_prealloc_dir_blocks; /* Nr to preallocate for dirs */
+ __u16 s_padding1;
+ /*
+ * Journaling support valid if EXT3_FEATURE_COMPAT_HAS_JOURNAL set.
+ */
+ __u8 s_journal_uuid[16]; /* uuid of journal superblock */
+ __u32 s_journal_inum; /* inode number of journal file */
+ __u32 s_journal_dev; /* device number of journal file */
+ __u32 s_last_orphan; /* start of list of inodes to delete */
+ __u32 s_hash_seed[4]; /* HTREE hash seed */
+ __u8 s_def_hash_version; /* Default hash version to use */
+ __u8 s_reserved_char_pad;
+ __u16 s_reserved_word_pad;
+ __u32 s_default_mount_opts;
+ __u32 s_first_meta_bg; /* First metablock block group */
+ __u32 s_reserved[190]; /* Padding to the end of the block */
};
struct ext2_group_desc
@@ -213,6 +256,9 @@
#define EXT2_ADDR_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof (__u32))
#define EXT2_ADDR_PER_BLOCK_BITS(s) (log2(EXT2_ADDR_PER_BLOCK(s)))
+#define EXT2_INODE_SIZE(s) (SUPERBLOCK->s_inode_size)
+#define EXT2_INODES_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s)/EXT2_INODE_SIZE(s))
+
/* linux/ext2_fs.h */
#define EXT2_BLOCK_SIZE_BITS(s) (le32_to_cpu((s)->s_log_block_size) + 10)
/* kind of from ext2/super.c */
@@ -582,12 +628,12 @@
gdp = GROUP_DESC;
ino_blk = le32_to_cpu(gdp[desc].bg_inode_table) +
(((current_ino - 1) % le32_to_cpu(SUPERBLOCK->s_inodes_per_group))
- >> log2 (EXT2_BLOCK_SIZE (SUPERBLOCK) / sizeof (struct ext2_inode)));
+ >> log2 (EXT2_INODES_PER_BLOCK (SUPERBLOCK)));
#ifdef E2DEBUG
printf ("ext2fs_dir: itab_blk=%d, i_in_grp=%d, log2=%d\n",
le32_to_cpu(gdp[desc].bg_inode_table),
((current_ino - 1) % le32_to_cpu(SUPERBLOCK->s_inodes_per_group)),
- log2 (EXT2_BLOCK_SIZE (SUPERBLOCK) / sizeof (struct ext2_inode)));
+ log2 (EXT2_INODES_PER_BLOCK (SUPERBLOCK)));
printf ("ext2fs_dir: inode table fsblock=%d\n", ino_blk);
#endif /* E2DEBUG */
if (!ext2_rdfsb (ino_blk, INODE))
@@ -598,13 +644,13 @@
/* reset indirect blocks! */
mapblock2 = mapblock1 = -1;
- raw_inode = INODE +
- ((current_ino - 1)
- & (EXT2_BLOCK_SIZE (SUPERBLOCK) / sizeof (struct ext2_inode) - 1));
+ raw_inode = (struct ext2_inode *)( (unsigned long)INODE +
+ ((current_ino - 1) & (EXT2_INODES_PER_BLOCK (SUPERBLOCK) - 1))
+ * EXT2_INODE_SIZE(SUPERBLOCK));
#ifdef E2DEBUG
printf ("ext2fs_dir: ipb=%d, sizeof(inode)=%d\n",
- (EXT2_BLOCK_SIZE (SUPERBLOCK) / sizeof (struct ext2_inode)),
- sizeof (struct ext2_inode));
+ EXT2_INODES_PER_BLOCK (SUPERBLOCK),
+ EXT2_INODE_SIZE(SUPERBLOCK));
printf ("ext2fs_dir: inode=%x, raw_inode=%x\n", INODE, raw_inode);
printf ("ext2fs_dir: offset into inode table block=%d\n", (int) raw_inode - (int) INODE);
dump_inode(raw_inode);
Modified: trunk/filo/include/grub/shared.h
===================================================================
--- trunk/filo/include/grub/shared.h 2008-10-18 20:29:55 UTC (rev 82)
+++ trunk/filo/include/grub/shared.h 2008-10-22 11:19:52 UTC (rev 83)
@@ -286,7 +286,6 @@
/* misc */
void init_page (void);
void print_error (void);
-char *convert_to_ascii (char *buf, int c, ...);
int get_cmdline (char *prompt, char *cmdline, int maxlen,
int echo_char, int history);
int substring (const char *s1, const char *s2);
Modified: trunk/filo/main/filo.c
===================================================================
--- trunk/filo/main/filo.c 2008-10-18 20:29:55 UTC (rev 82)
+++ trunk/filo/main/filo.c 2008-10-22 11:19:52 UTC (rev 83)
@@ -16,6 +16,7 @@
*/
#include <libpayload.h>
+#include <libpayload-config.h>
#include <config.h>
#include <version.h>
#include <lib.h>
@@ -59,10 +60,19 @@
collect_sys_info(&sys_info);
relocate();
-#if defined(CONFIG_USB_DISK) || defined(CONFIG_USB_NEW_DISK)
+#if defined(CONFIG_USB_DISK)
usb_initialize();
#endif
+#if defined(CONFIG_USB_NEW_DISK)
+#if defined(CONFIG_USB)
+ /* libpayload USB stack is there */
+ usb_initialize();
+#else
+ printf("No USB stack in libpayload.\n");
+#endif
+#endif
+
#ifdef CONFIG_SUPPORT_SOUND
sound_init();
#endif
@@ -91,17 +101,15 @@
free(file);
}
-
-void __attribute__((weak)) platform_reboot(void)
-{
- printf("Rebooting not supported.\n");
-}
-
void reset_handler(void)
{
- void platform_reboot(void);
+ void __attribute__((weak)) platform_reboot(void);
- platform_reboot();
+ if (platform_reboot)
+ platform_reboot();
+ else
+ printf("Rebooting not supported.\n");
+
}
#if CONFIG_USE_GRUB
Modified: trunk/filo/main/grub/builtins.c
===================================================================
--- trunk/filo/main/grub/builtins.c 2008-10-18 20:29:55 UTC (rev 82)
+++ trunk/filo/main/grub/builtins.c 2008-10-22 11:19:52 UTC (rev 83)
@@ -27,6 +27,7 @@
#ifdef CONFIG_USE_MD5_PASSWORDS
#include <grub/md5.h>
#endif
+#include <pci.h>
/* The default entry. */
int default_entry = 0;
@@ -615,8 +616,115 @@
};
+#ifdef CONFIG_DEVELOPER_TOOLS
+/* io */
+static int io_func(char *arg, int flags)
+{
+ char *walk = arg;
+ unsigned int port = 0;
+ unsigned int value = 0;
+ unsigned int write_mode = 0;
+ unsigned int maxval=0xff, len=1;
+ while ((*walk != 0) && (*walk != '.') && (*walk != '=')) {
+ port *= 16;
+ port += hex2bin(*walk);
+ walk++;
+ }
+ if (port > 0xffff) {
+ grub_printf("port too high\n");
+ errnum = ERR_BAD_ARGUMENT;
+ return 1;
+ }
+ if (*walk == '.') {
+ walk++;
+ switch (*walk) {
+ case 'l':
+ case 'L':
+ len = 4;
+ maxval = 0xffffffff;
+ break;
+ case 'w':
+ case 'W':
+ len=2;
+ maxval = 0xffff;
+ break;
+ case 'b':
+ case 'B':
+ len=1;
+ maxval = 0xff;
+ break;
+ default:
+ grub_printf("width must be b, w, or l\n");
+ errnum = ERR_BAD_ARGUMENT;
+ return 1;
+ }
+ walk++;
+ }
+
+ if (*walk == '=') {
+ while (*walk!=0 && *walk != '.') {
+ value *= 16;
+ value += hex2bin(*walk);
+ walk++;
+ }
+
+ if (value > maxval) {
+ grub_printf("value too big.\n");
+ errnum = ERR_BAD_ARGUMENT;
+ return 1;
+ }
+
+ write_mode = 1;
+ }
+
+ if (write_mode) {
+ grub_printf ("out");
+ switch (len) {
+ case 1:
+ grub_printf("b 0x%02x -> 0x%04x\n", value, port);
+ outb(value, port);
+ break;
+ case 2:
+ grub_printf("w 0x%04x -> 0x%04x\n", value, port);
+ outw(value, port);
+ break;
+ case 4:
+ grub_printf("l 0x%08x -> 0x%04x\n", value, port);
+ outl(value, port);
+ break;
+ }
+ } else {
+ grub_printf ("in");
+ switch (len) {
+ case 1:
+ value = inb(port);
+ grub_printf("b 0x%04x: 0x%02x\n", port, value);
+ break;
+ case 2:
+ value = inw(port);
+ grub_printf("w 0x%04x: 0x%04x\n", port, value);
+ break;
+ case 4:
+ value = inl(port);
+ grub_printf("l 0x%04x: 0x%08x\n", port, value);
+ break;
+ }
+ }
+
+ return 0;
+}
+
+static struct builtin builtin_io = {
+ "io",
+ io_func,
+ BUILTIN_MENU | BUILTIN_CMDLINE | BUILTIN_HELP_LIST | BUILTIN_NO_ECHO,
+ "io port[.bwl][=val]",
+ "Read/write IO ports."
+};
+#endif
+
/* kernel */
static int kernel_func(char *arg, int flags)
{
@@ -681,6 +789,117 @@
"Break a command execution unless the user is authenticated."
};
+#ifdef CONFIG_DEVELOPER_TOOLS
+static int lspci_indent = 0;
+static void lspci_scan_bus(int bus)
+{
+ int slot, func;
+ unsigned int val;
+ unsigned char hdr;
+ int i;
+
+ for (slot = 0; slot < 0x20; slot++) {
+ for (func = 0; func < 8; func++) {
+ pcidev_t dev = PCI_DEV(bus, slot, func);
+
+ val = pci_read_config32(dev, REG_VENDOR_ID);
+
+ /* Nobody home. */
+ if (val == 0xffffffff || val == 0x00000000 ||
+ val == 0x0000ffff || val == 0xffff0000)
+ continue;
+
+ for (i=0; i<lspci_indent; i++)
+ grub_printf("| ");
+ grub_printf("|- %x:%x.%x [%x:%x]\n", bus, slot, func,
+ val & 0xffff, val >> 16);
+
+ /* If this is a bridge, then follow it. */
+ hdr = pci_read_config8(dev, REG_HEADER_TYPE);
+ hdr &= 0x7f;
+ if (hdr == HEADER_TYPE_BRIDGE ||
+ hdr == HEADER_TYPE_CARDBUS) {
+ unsigned int busses;
+
+ busses = pci_read_config32(dev, REG_PRIMARY_BUS);
+ lspci_indent++;
+ lspci_scan_bus((busses >> 8) & 0xff);
+ lspci_indent--;
+ }
+ }
+ }
+}
+
+static void lspci_configspace(pcidev_t dev)
+{
+ unsigned char cspace[256];
+ int i, x, y;
+
+ for (i = 0; i < 256; i ++)
+ cspace[i] = pci_read_config8(dev, i);
+
+ for (y = 0; y < 16; y++) {
+ grub_printf("%x0:", y);
+ for (x = 0; x < 16; x++)
+ grub_printf(" %02x", cspace[(y * 16) + x]);
+ grub_printf("\n");
+ }
+
+ grub_printf("\n");
+}
+
+static int lspci_func(char *arg, int flags)
+{
+ char *walk = arg;
+ int bus, slot, fn;
+
+ if(strlen(walk)) {
+ pcidev_t dev;
+
+ if((walk[1] != ':') && (walk[2] =! ':'))
+ goto out;
+ if(walk[1] == ':') {
+ bus = hex2bin(walk[0]);
+ walk+=2;
+ } else {
+ bus = (hex2bin(walk[0]) * 16) + hex2bin(walk[1]);
+ walk+=3;
+ }
+ if((walk[1] != '.') && (walk[2] =! '.'))
+ goto out;
+
+ if(walk[1] == '.') {
+ slot = hex2bin(walk[0]);
+ walk+=2;
+ } else {
+ slot = (hex2bin(walk[0]) * 16) + hex2bin(walk[1]);
+ walk+=3;
+ }
+ if (!walk[0])
+ goto out;
+
+ fn=hex2bin(walk[0]);
+
+ grub_printf("Dumping %x:%x.%x\n", bus, slot, fn);
+
+ dev = PCI_DEV(bus, slot, fn);
+ lspci_configspace(dev);
+ return 0;
+ }
+out:
+ lspci_scan_bus(0);
+ return 0;
+}
+
+static struct builtin builtin_lspci = {
+ "lspci",
+ lspci_func,
+ BUILTIN_MENU | BUILTIN_CMDLINE | BUILTIN_HELP_LIST | BUILTIN_NO_ECHO,
+ "lspci <device>",
+ "Show PCI devices or dump PCI config space"
+};
+#endif
+
#ifdef CONFIG_USE_MD5_PASSWORDS
/* md5crypt */
static int md5crypt_func(char *arg, int flags)
@@ -817,14 +1036,13 @@
"Print MESSAGE, then wait until a key is pressed."
};
-void __attribute__((weak)) platform_poweroff(void)
-{
- grub_printf("Poweroff not supported.\n");
-}
-
static int poweroff_func(char *arg, int flags)
{
- platform_poweroff();
+ void __attribute__((weak)) platform_poweroff(void);
+ if (platform_poweroff)
+ platform_poweroff();
+ else
+ grub_printf("Poweroff not supported.\n");
// Will (hopefully) never return;
return 0;
@@ -838,11 +1056,38 @@
"Power off the system."
};
+#ifdef CONFIG_DEVELOPER_TOOLS
+static int probe_func(char *arg, int flags)
+{
+#if CONFIG_IDE_DISK
+ int i;
+
+ for (i=0; i<8; i++)
+ ide_probe(i);
+#else
+ grub_printf("No IDE driver.\n");
+#endif
+
+ return 0;
+}
+
+static struct builtin builtin_probe = {
+ "probe",
+ probe_func,
+ BUILTIN_CMDLINE | BUILTIN_HELP_LIST,
+ "probe",
+ "Probe IDE drives"
+};
+#endif
+
static int reboot_func(char *arg, int flags)
{
- void platform_reboot(void);
+ void __attribute__((weak)) platform_reboot(void);
- platform_reboot();
+ if (platform_reboot)
+ platform_reboot();
+ else
+ grub_printf("Reboot not supported.\n");
// Will (hopefully) never return;
return 0;
@@ -884,10 +1129,8 @@
"Set the current \"root device\" to the device DEVICE."
};
-void __attribute__((weak)) serial_hardware_init(int port, int speed, int word_bits, int parity, int stop_bits)
-{
- grub_printf("This version of FILO does not have serial console support.\n");
-}
+void __attribute__((weak)) serial_hardware_init(int port, int speed, int
+ word_bits, int parity, int stop_bits);
/* serial */
static int serial_func(char *arg, int flags)
@@ -987,7 +1230,10 @@
}
/* Initialize the serial unit. */
- serial_hardware_init(port, speed, word_len, parity, stop_bit_len);
+ if (serial_hardware_init)
+ serial_hardware_init(port, speed, word_len, parity, stop_bit_len);
+ else
+ grub_printf("This version of FILO does not have serial console support.\n");
return 0;
}
@@ -1006,8 +1252,163 @@
" default values are COM1, 9600, 8N1."
};
+#ifdef CONFIG_DEVELOPER_TOOLS
+static int setpci_func(char *arg, int flags)
+{
+ char *walk = arg;
+ int bus, slot, fn;
+ pcidev_t dev;
+ unsigned int reg=0;
+ unsigned int len=1, maxval=0xff, value=0;
+ int write_mode = 0;
+ // setpci bus:dev.fn reg.[bwl][=val]
+ if(!strlen(arg)) {
+ errnum = ERR_BAD_ARGUMENT;
+ return 1;
+ }
+
+ if((walk[1] != ':') && (walk[2] =! ':')) {
+ errnum = ERR_BAD_ARGUMENT;
+ return 1;
+ }
+
+ if(walk[1] == ':') {
+ bus = hex2bin(walk[0]);
+ walk+=2;
+ } else {
+ bus = (hex2bin(walk[0]) * 16) + hex2bin(walk[1]);
+ walk+=3;
+ }
+ if((walk[1] != '.') && (walk[2] =! '.')) {
+ errnum = ERR_BAD_ARGUMENT;
+ return 1;
+ }
+
+ if(walk[1] == '.') {
+ slot = hex2bin(walk[0]);
+ walk+=2;
+ } else {
+ slot = (hex2bin(walk[0]) * 16) + hex2bin(walk[1]);
+ walk+=3;
+ }
+ if (!walk[0]) {
+ errnum = ERR_BAD_ARGUMENT;
+ return 1;
+ }
+
+ fn=hex2bin(walk[0]);
+
+ dev = PCI_DEV(bus, slot, fn);
+
+ walk++;
+ if (walk[0] != ' ') {
+ grub_printf("No register specified\n");
+ errnum = ERR_BAD_ARGUMENT;
+ return 1;
+ }
+
+ while (*walk!=0 && *walk != '.' && *walk != ':' ) {
+ reg *= 16;
+ reg += hex2bin(*walk);
+ walk++;
+ }
+
+ if (reg > 0xff) {
+ grub_printf("Only 256 byte config space supported.\n");
+ errnum = ERR_BAD_ARGUMENT;
+ return 1;
+ }
+
+ if (*walk == '.') {
+ walk++;
+ switch (*walk) {
+ case 'l':
+ case 'L':
+ len = 4;
+ maxval = 0xffffffff;
+ break;
+ case 'w':
+ case 'W':
+ len=2;
+ maxval = 0xffff;
+ break;
+ case 'b':
+ case 'B':
+ len=1;
+ maxval = 0xff;
+ break;
+ default:
+ grub_printf("width must be b, w, or l\n");
+ errnum = ERR_BAD_ARGUMENT;
+ return 1;
+ }
+ walk++;
+ }
+
+ if (*walk == '=') {
+ while (*walk!=0 && *walk != '.') {
+ value *= 16;
+ value += hex2bin(*walk);
+ walk++;
+ }
+
+ if (value > maxval) {
+ grub_printf("value too big.\n");
+ errnum = ERR_BAD_ARGUMENT;
+ return 1;
+ }
+
+ write_mode = 1;
+ }
+
+ if (write_mode) {
+ grub_printf ("pci_write_config");
+ switch (len) {
+ case 1:
+ grub_printf("8 0x%02x -> %x:%x.%x [%02x]\n", value, bus, slot, fn, reg);
+ pci_write_config8(dev, reg, value);
+ break;
+ case 2:
+ grub_printf("16 0x%04x -> %x:%x.%x [%02x]\n", value, bus, slot, fn, reg);
+ pci_write_config16(dev, reg, value);
+ break;
+ case 4:
+ grub_printf("32 0x%08x -> %x:%x.%x [%02x]\n", value, bus, slot, fn, reg);
+ pci_write_config32(dev, reg, value);
+ break;
+ }
+ } else {
+ grub_printf ("pci_read_config");
+ switch (len) {
+ case 1:
+ value = pci_read_config8(dev, reg);
+ grub_printf("8 %x:%x.%x [%02x] -> %02x\n", bus, slot, fn, reg, value);
+ break;
+ case 2:
+ value = pci_read_config16(dev, reg);
+ grub_printf("16 %x:%x.%x [%02x] -> %04x\n", bus, slot, fn, reg, value);
+ break;
+ case 4:
+ value = pci_read_config32(dev, reg);
+ grub_printf("32 %x:%x.%x [%02x] -> %08x\n", bus, slot, fn, reg, value);
+ break;
+ }
+ }
+
+ return 0;
+}
+
+static struct builtin builtin_setpci = {
+ "setpci",
+ setpci_func,
+ BUILTIN_MENU | BUILTIN_CMDLINE | BUILTIN_HELP_LIST | BUILTIN_NO_ECHO,
+ "setpci <device>[.bwl][=value]",
+ "Show/change PCI config space values"
+};
+#endif
+
/* terminal */
static int terminal_func(char *arg, int flags)
{
@@ -1145,7 +1546,7 @@
keymap_func,
BUILTIN_MENU | BUILTIN_CMDLINE | BUILTIN_HELP_LIST | BUILTIN_NO_ECHO,
"keymap LANGCODE",
- "Select a keymap to use. Currently only 'en' and 'de' are supported."
+ "Select a keymap to use. Currently only 'us' and 'de' are supported."
};
static int title_func(char *arg, int flags)
@@ -1179,18 +1580,30 @@
&builtin_help,
&builtin_hiddenmenu,
&builtin_initrd,
+#ifdef CONFIG_DEVELOPER_TOOLS
+ &builtin_io,
+#endif
&builtin_kernel,
&builtin_keymap,
&builtin_lock,
+#ifdef CONFIG_DEVELOPER_TOOLS
+ &builtin_lspci,
+#endif
#ifdef CONFIG_USE_MD5_PASSWORDS
&builtin_md5crypt,
#endif
&builtin_password,
&builtin_pause,
&builtin_poweroff,
+#ifdef CONFIG_DEVELOPER_TOOLS
+ &builtin_probe,
+#endif
&builtin_reboot,
&builtin_root,
&builtin_serial,
+#ifdef CONFIG_DEVELOPER_TOOLS
+ &builtin_setpci,
+#endif
&builtin_terminal,
&builtin_timeout,
&builtin_title,
Modified: trunk/filo/main/grub/char_io.c
===================================================================
--- trunk/filo/main/grub/char_io.c 2008-10-18 20:29:55 UTC (rev 82)
+++ trunk/filo/main/grub/char_io.c 2008-10-22 11:19:52 UTC (rev 83)
@@ -73,42 +73,6 @@
grub_printf("\nError %u: %s\n", errnum, err_list[errnum]);
}
-char *convert_to_ascii(char *buf, int c, ...)
-{
- unsigned long num = *((&c) + 1), mult = 10;
- char *ptr = buf;
-
- if (c == 'x' || c == 'X')
- mult = 16;
-
- if ((num & 0x80000000uL) && c == 'd') {
- num = (~num) + 1;
- *(ptr++) = '-';
- buf++;
- }
-
- do {
- int dig = num % mult;
- *(ptr++) = ((dig > 9) ? dig + 'a' - 10 : '0' + dig);
- }
- while (num /= mult);
-
- /* reorder to correct direction!! */
- {
- char *ptr1 = ptr - 1;
- char *ptr2 = buf;
- while (ptr1 > ptr2) {
- int tmp = *ptr1;
- *ptr1 = *ptr2;
- *ptr2 = tmp;
- ptr1--;
- ptr2++;
- }
- }
-
- return ptr;
-}
-
void grub_putstr(const char *str)
{
while (*str)
@@ -117,35 +81,17 @@
void grub_printf(const char *format, ...)
{
- int *dataptr = (int *) &format;
- char c, str[16];
+ int ret;
+ va_list args;
+#define OUTPUT_SIZE 256
+ char output[OUTPUT_SIZE];
- dataptr++;
-
- while ((c = *(format++)) != 0) {
- if (c != '%')
- grub_putchar(c);
- else
- switch (c = *(format++)) {
- case 'd':
- case 'x':
- case 'X':
- case 'u':
- *convert_to_ascii(str, c, *((unsigned long *)
- dataptr++)) = 0;
- grub_putstr(str);
- break;
-
- case 'c':
- grub_putchar((*(dataptr++)) & 0xff);
- break;
-
- case 's':
- grub_putstr((char *) *(dataptr++));
- break;
- }
- }
+ va_start(args, format);
+ ret = vsnprintf(output, OUTPUT_SIZE, format, args);
+ va_end(args);
+ grub_putstr(output);
refresh();
+#undef OUTPUT_SIZE
}
void init_page(void)
Modified: trunk/filo/main/grub/cmdline.c
===================================================================
--- trunk/filo/main/grub/cmdline.c 2008-10-18 20:29:55 UTC (rev 82)
+++ trunk/filo/main/grub/cmdline.c 2008-10-22 11:19:52 UTC (rev 83)
@@ -139,9 +139,18 @@
print_error();
errnum = ERR_NONE;
+ short col1, col2, col3, col4;
+ pair_content(1, &col1, &col2);
+ pair_content(2, &col3, &col4);
+ /* reset to light-gray-on-black on console */
+ console_setcolor(0x07, 0x70);
+
/* Get the command-line with the minimal BASH-like interface. */
- if (get_cmdline(CONFIG_PROMPT "> ", heap, 2048, 0, 1))
+ if (get_cmdline(CONFIG_PROMPT "> ", heap, 2048, 0, 1)) {
+ init_pair(1, col1, col2);
+ init_pair(2, col3, col4);
return;
+ }
/* If there was no command, grab a new one. */
if (!heap[0])
@@ -195,7 +204,7 @@
intervention. */
if (fallback_entryno < 0) {
grub_printf("\nPress any key to continue...");
- (void) getkey();
+ (void) getchar();
}
return 1;
Modified: trunk/filo/main/grub/grub.c
===================================================================
--- trunk/filo/main/grub/grub.c 2008-10-18 20:29:55 UTC (rev 82)
+++ trunk/filo/main/grub/grub.c 2008-10-22 11:19:52 UTC (rev 83)
@@ -138,6 +138,8 @@
strcpy(menulst, bootdevice);
strncat(menulst, filename, 256);
+ /* Set string to zero: */
+ config_file[0] = 0;
copy_path_to_filo_bootline(menulst, config_file, 0);
if (file_open(config_file)) {
/* We found a config file. Bail out */
@@ -634,6 +636,8 @@
if (config_entries)
run_menu(heap, NULL, new_num_entries, new_heap, 0);
else {
+ /* flush color map */
+ grub_printf(" ");
cls();
print_cmdline_message(CMDLINE_EDIT_MODE);
@@ -800,7 +804,6 @@
break;
}
- for (;;);
show_menu = 1;
goto restart;
}
Modified: trunk/filo/util/checksum_elf.c
===================================================================
--- trunk/filo/util/checksum_elf.c 2008-10-18 20:29:55 UTC (rev 82)
+++ trunk/filo/util/checksum_elf.c 2008-10-22 11:19:52 UTC (rev 83)
@@ -28,6 +28,16 @@
#else
#include "byteorder.h"
#endif
+#if defined(__sun)
+#include <sys/isa_defs.h>
+#define LITTLE_ENDIAN 1
+#define BIG_ENDIAN 2
+#if defined(_LITTLE_ENDIAN)
+#define BYTE_ORDER LITTLE_ENDIAN
+#else
+#define BYTE_ORDER BIG_ENDIAN
+#endif
+#endif
#define STDINT_H
#include "elf.h"
#include "elf_boot.h"