librecore-org / librecore

GNU General Public License v2.0
88 stars 10 forks source link

[grub] Optimize GRUB configuration to work well on ICH7 boards #5

Closed ghost closed 7 years ago

ghost commented 7 years ago

When using the GRUB payload on the ga-945gcm-s2l, ATA disks aren't detected at all. Running ls only shows USB devices.

Probably GRUB misses a required module for this board.

zamaudio commented 7 years ago

Sorry guys you're on your own on this one, I don't have any i945 boards.

ArthurHeymans commented 7 years ago

I think I stripped down GRUB too much too fit it in 512M. Its just ich7 so I doubt its really coreboot related.

ghost commented 7 years ago

@ArthurHeymans I'm still very interested in having GRUB on this board, so I'd like to help finding a working GRUB configuration.

ghost commented 7 years ago

I have successfully made a grub.elf small enough to fit 512kB chips. It was pretty straightforward.

git clone git://git.savannah.gnu.org/grub.git
cd grub
make clean
./autogen.sh
./configure --with-platform=coreboot
make

Followed by:

make default_payload.elf
        pkgdatadir=. ./grub-mkstandalone --grub-mkimage=./grub-mkimage -O i386-coreboot -o default_payload.elf --modules='affs afs ahci all_video ata at_keyboard bfs btrfs cbfs cmosdump cmostest cpio cpio_be cryptodisk disk diskfilter ehci exfat ext2 fat gfxterm_background hdparm hfs hfsplus iso9660 jfs jpeg keystatus minix minix2 minix2_be minix3 minix3_be minix_be nativedisk newc nilfs2 ntfs odc ohci part_gpt part_msdos pata play png probe reiserfs romfs sfs squash4 syslinuxcfg testload testspeed udf ufs1 ufs1_be ufs2 uhci usb_keyboard usbms usbserial_ftdi usbserial_pl2303 usbserial_usbdebug usbtest videoinfo videotest xfs zfs' --install-modules='cbls cbmemc cbtime chain configfile date datetime echo eval gzio halt help hexdump iorw linux linux16 ls lsacpi lsmmap lspci memrw minicmd multiboot normal pcidump reboot regexp search serial setpci test time' --fonts= --themes= --locales= -d grub-core/ /boot/grub/grub.cfg=./coreboot.cfg

Optionally, you can append a keymap file at the very end, behind ./coreboot.cfg:

/boot/grub/layouts/usdvorak.gkb=./usdvorak.gkb

Make sure to put the desired gkb file in the pkgdatadir first though, and change the names accordingly.

The same can also be done for fonts. Simply append /dejavusansmono.pf2=./dejavusansmono.pf2 to the end of the command.

This resulting _defaultpayload.elf can simply be selected from menuconfig.

It will ook for /etc/grub.cfg in cbfs. I started out with the one from the ga-g41m-es2l, but it has to be modified slightly for the ga-945gcm-s2l, as it doesn't address sata disks as ata0, ata1, ata2 and ata3, but as ata4, ata5, ata6 and ata7.

Tested on the ga-945gcm-s2l. GRUB works well / fast. I only haven't yet figured out an optimal grub.cfg.

ghost commented 7 years ago

This should work across all ICH7 boards:

prefix=(memdisk)/boot/grub

insmod nativedisk
insmod ehci
insmod ohci
insmod uhci
insmod usb
rmmod at_keyboard

# Serial and keyboard configuration
serial --speed=115200 --unit=0 --word=8 --parity=no --stop=1
terminal_input --append serial
terminal_output --append cbmemc
terminal_output --append gfxterm
terminal_output --append serial

# Use native graphics
gfxpayload=keep

# Default to first option, automatically boot after 1 second
set default="0"
set timeout=1

# This is useful when using 'cat' on long files on GRUB terminal
set pager=1

menuentry 'Load Operating System [o]' --hotkey='o' {
    insmod ata
    insmod part_msdos
    insmod part_gpt
    insmod regexp
    for x in (ata0,*) (ata2,*) (ata4,*) (ata6,*) (ata1,*) (ata3,*) (ata5,*) (ata7,*); do
        if [ -f "$x/grub/grub.cfg" ] ; then
            set root=$x
            configfile /grub/grub.cfg
        fi
        if [ -f "$x/boot/grub/grub.cfg" ] ; then
            set root=$x
            configfile /boot/grub/grub.cfg
        fi
    done

# Fallback mode
    set root='ata0,1'
    linux  /vmlinuz root=/dev/sda1 rw
    if [ -f "/initrd.img" ] ; then
        initrd /initrd.img
    fi
}

menuentry 'Parse ISOLINUX menu (USB) [u]' --hotkey='u' {
    insmod usbms
    insmod part_msdos
    insmod part_gpt
    insmod regexp
    for x in (usb0) (usb0,*); do
        set root=$x
        if [ -f "/isolinux/isolinux.cfg" ] ; then
            syslinux_configfile -i /isolinux/isolinux.cfg
        elif [ -f "/menu.cfg" ] ; then
            syslinux_configfile -i /menu.cfg
        elif [ -f "/txt.cfg" ] ; then
            syslinux_configfile -i /txt.cfg
        fi
    done
}

menuentry 'Parse ISOLINUX menu (CD/DVD) [d]' --hotkey='d' {
    insmod ata
    insmod iso9660
    insmod regexp
    for x in (ata0) (ata4) (ata2) (ata6) (ata1) (ata5) (ata3) (ata7); do
        set root=$x
        if [ -f "/isolinux/isolinux.cfg" ] ; then
            syslinux_configfile -i /isolinux/isolinux.cfg
        elif [ -f "/menu.cfg" ] ; then
            syslinux_configfile -i /menu.cfg
        elif [ -f "/txt.cfg" ] ; then
            syslinux_configfile -i /txt.cfg
        fi
    done
}

menuentry 'Search for GRUB configuration (grub.cfg) outside of CBFS [s]' --hotkey='s' {
    insmod usbms
    insmod part_msdos
    insmod part_gpt
    insmod regexp
    for x in (usb0) (usb0,*) (ata0,*) (ata4,*) (ata2,*) (ata6,*) (ata1,*) (ata5,*) (ata3,*) (ata7,*); do
        if [ -f "$x/grub/grub.cfg" ] ; then
            submenu "Load Config from $x" $x { 
                root=$2
                source /grub/grub.cfg
                unset superusers
            }
        fi
        if [ -f "$x/boot/grub/grub.cfg" ] ; then
            submenu "Load Config from $x" $x {
                root=$2
                source /boot/grub/grub.cfg
                unset superusers
            }
        fi
    done
}

menuentry 'Poweroff  [p]' --hotkey='p' {
    halt
}

menuentry 'Reboot  [r]' --hotkey='r' {
    reboot
}
ghost commented 7 years ago

It probably makes sense to use different config files for different targets, to avoid wasting time probing for disks that simply aren't present.

Also, the order should probably be changed. Because ich7 uses ide mode, sata ports now have "master and slave". So SATA2_0 is is ata1.00, SATA2_1 is ata1.01, SATA2_2 is ata2.00 and SATA2_3 is ata2.01.

Meaning that on the ga-g41m-es2l, we should probably use this:

for x in (ata0,1) (ata0,2) (ata0,3) (ata0,4) (ata2,1) (ata2,2) (ata2,3) (ata2,4) (ata1,1) (ata1,2) (ata1,3) (ata1,4) (ata3,1) (ata3,2) (ata3,3) (ata3,4); do

And on the ga-945gcm-s2l, we should probably do this:

for x in (ata4,1) (ata4,2) (ata4,3) (ata4,4) (ata6,1) (ata6,2) (ata6,3) (ata6,4) (ata5,1) (ata5,2) (ata5,3) (ata5,4) (ata7,1) (ata7,2) (ata7,3) (ata7,4); do

This first probes the master channels (0 and 2), and then the slave channels (1 and 3).

The fallback mode should also be different across the boards: (ata0,1) on the ga-g41m-es2l and (ata4,1) on the ga-945gcm-s2l.

Same goes for isolinux probing, and so on...

ghost commented 7 years ago

Most likely, we can use the regexp module to simplify this even further:

for x in (ata0,*) (ata2,*) (ata1,*) (ata3,*); do

and

for x in (ata4,*) (ata6,*) (ata5,*) (ata7,*); do

This is just very, very slow at the moment due to issue #3.

ghost commented 7 years ago

I have created a wiki page to further optimize this situation. For now, it just works, but improvements are always welcome.