├── grub-shusher ├── .gitignore ├── Makefile ├── .gitrepo ├── setup-debian.sh ├── LICENSE ├── grub-kernel.c ├── mbr.c └── README.md ├── etc ├── systemd │ ├── journald.conf.d │ │ ├── 00-journal-size.conf │ │ └── fw-tty4.conf │ └── logind.conf ├── udev │ └── rules.d │ │ └── 60-ioschedulers.rules ├── mkinitcpio.conf └── makepkg.conf ├── LICENSE └── README.md /grub-shusher/.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | mbr 3 | grub-kernel 4 | grub-kernel.o 5 | -------------------------------------------------------------------------------- /etc/systemd/journald.conf.d/00-journal-size.conf: -------------------------------------------------------------------------------- 1 | [Journal] 2 | SystemMaxUse=50M 3 | -------------------------------------------------------------------------------- /etc/systemd/journald.conf.d/fw-tty4.conf: -------------------------------------------------------------------------------- 1 | [Journal] 2 | ForwardToConsole=yes 3 | TTYPath=/dev/tty4 4 | MaxLevelConsole=info 5 | -------------------------------------------------------------------------------- /grub-shusher/Makefile: -------------------------------------------------------------------------------- 1 | # gnu99 is required only for the memmem function, for 2 | # which there doesn't seem to be any POSIX equivalent? 3 | CFLAGS = -std=gnu99 -Wall -pedantic 4 | 5 | all: mbr grub-kernel 6 | 7 | grub-kernel: grub-kernel.o 8 | 9 | mbr: mbr.o 10 | 11 | mbr.o: mbr.c 12 | 13 | mbr.o: grub-kernel.c 14 | 15 | clean: 16 | rm -f grub-kernel mbr ./*.o 17 | -------------------------------------------------------------------------------- /etc/udev/rules.d/60-ioschedulers.rules: -------------------------------------------------------------------------------- 1 | # set scheduler for NVMe 2 | ACTION=="add|change", KERNEL=="nvme[0-9]*", ATTR{queue/scheduler}="none" 3 | # set scheduler for SSD and eMMC 4 | ACTION=="add|change", KERNEL=="sd[a-z]|mmcblk[0-9]*", ATTR{queue/rotational}=="0", ATTR{queue/scheduler}="mq-deadline" 5 | # set scheduler for rotating disks 6 | ACTION=="add|change", KERNEL=="sd[a-z]", ATTR{queue/rotational}=="1", ATTR{queue/scheduler}="bfq" 7 | -------------------------------------------------------------------------------- /grub-shusher/.gitrepo: -------------------------------------------------------------------------------- 1 | ; DO NOT EDIT (unless you know what you are doing) 2 | ; 3 | ; This subdirectory is a git "subrepo", and this file is maintained by the 4 | ; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme 5 | ; 6 | [subrepo] 7 | remote = https://github.com/ccontavalli/grub-shusher.git 8 | branch = master 9 | commit = f00f43486392eca910042656b90914827dc50381 10 | parent = e638fe44cbdb874217a02ec9632d5a12a564ac80 11 | method = merge 12 | update = auto 13 | cmdver = 0.4.1 14 | -------------------------------------------------------------------------------- /grub-shusher/setup-debian.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Configures grub-shusher on a debian system. Suitable to be 4 | # invoked from apt.conf, as a post invoke script. See README.md 5 | # for more details. 6 | 7 | set -e 8 | 9 | # If no disk was provided, exit with error. 10 | test -n "$1" || { 11 | echo "Use: $0 DISK" 1>&2 12 | echo 1>&2 13 | echo "For example: $0 /dev/sda" 1>&2 14 | echo 1>&2 15 | echo "You need to specify the grub installation disk." 1>&2 16 | exit 1 17 | } 18 | 19 | # Enter the directory where grub-shusher was installed. 20 | cd "$(dirname "$(readlink -f "$(which "$0")")")" 21 | 22 | # Compile and run it. 23 | make 24 | ./mbr "$1" 25 | 26 | # On modern debian system, this may fail, and may be benign. 27 | ( 28 | set +e 29 | ./grub-kernel /boot/grub/kernel.img 30 | ./grub-kernel /boot/grub/i386-pc/kernel.img 31 | ./grub-kernel /usr/lib/grub/i386-pc/kernel.img 32 | grub-install "$1" 33 | ./mbr "$1" 34 | ) 35 | -------------------------------------------------------------------------------- /etc/systemd/logind.conf: -------------------------------------------------------------------------------- 1 | # This file is part of systemd. 2 | # 3 | # systemd is free software; you can redistribute it and/or modify it 4 | # under the terms of the GNU Lesser General Public License as published by 5 | # the Free Software Foundation; either version 2.1 of the License, or 6 | # (at your option) any later version. 7 | # 8 | # Entries in this file show the compile time defaults. 9 | # You can change settings by editing this file. 10 | # Defaults can be restored by simply deleting this file. 11 | # 12 | # See logind.conf(5) for details. 13 | 14 | [Login] 15 | NAutoVTs=4 16 | #ReserveVT=6 17 | #KillUserProcesses=no 18 | #KillOnlyUsers= 19 | #KillExcludeUsers=root 20 | #InhibitDelayMaxSec=5 21 | #HandlePowerKey=poweroff 22 | #HandleSuspendKey=suspend 23 | #HandleHibernateKey=hibernate 24 | #HandleLidSwitch=suspend 25 | #HandleLidSwitchExternalPower=suspend 26 | #HandleLidSwitchDocked=ignore 27 | #PowerKeyIgnoreInhibited=no 28 | #SuspendKeyIgnoreInhibited=no 29 | #HibernateKeyIgnoreInhibited=no 30 | #LidSwitchIgnoreInhibited=yes 31 | HoldoffTimeoutSec=30s 32 | #IdleAction=ignore 33 | #IdleActionSec=30min 34 | #RuntimeDirectorySize=10% 35 | #RemoveIPC=yes 36 | #InhibitorsMax=8192 37 | #SessionsMax=8192 38 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /grub-shusher/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012,2013 Carlo Contavalli (ccontavalli@gmail.com). 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, 8 | this list of conditions and the following disclaimer. 9 | 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY Carlo Contavalli ''AS IS'' AND ANY EXPRESS OR 15 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 16 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 17 | EVENT SHALL Carlo Contavalli OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 18 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 21 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | 25 | The views and conclusions contained in the software and documentation are 26 | those of the authors and should not be interpreted as representing official 27 | policies, either expressed or implied, of Carlo Contavalli. 28 | -------------------------------------------------------------------------------- /grub-shusher/grub-kernel.c: -------------------------------------------------------------------------------- 1 | #define _GNU_SOURCE 2 | 3 | #include 4 | 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | int main(int argc, char** argv) { 14 | if (argc != 2) { 15 | fprintf(stderr, "Usage: grub-kernel /path/to/grub/kernel.img\n"); 16 | fprintf(stderr, "\nYou need to provide one path to kernel.img, generally\n"); 17 | fprintf(stderr, "/boot/grub/kernel.img\n"); 18 | return 1; 19 | } 20 | 21 | int fd = open(argv[1], O_RDONLY); 22 | if (fd < 0) { 23 | fprintf(stderr, "Could not open for read %s: %s\n", argv[1], strerror(errno)); 24 | return 1; 25 | } 26 | printf("opened: %s\n", argv[1]); 27 | 28 | char buffer[1024 * 1024]; 29 | int data = read(fd, buffer, sizeof(buffer)); 30 | if (data < 0) { 31 | fprintf(stderr, "Could not read %s: %s\n", argv[1], strerror(errno)); 32 | return 2; 33 | } 34 | close(fd); 35 | 36 | printf("read: %d bytes from %s\n", data, argv[1]); 37 | 38 | # define DECLARE_MATCH(str) { str, sizeof(str) - 1 } 39 | struct { 40 | const char* match; 41 | const int length; 42 | } matches[] = { 43 | DECLARE_MATCH("Welcome to GRUB!\n\n\0"), 44 | }; 45 | 46 | int found = 0; 47 | for (int i = 0; i < sizeof(matches) / sizeof(matches[0]); ++i) { 48 | const char* match = matches[i].match; 49 | const int length = matches[i].length; 50 | 51 | void* ptr = memmem(buffer, data, match, length); 52 | if (!ptr) { 53 | printf("match[%d]: NOT FOUND\n", i); 54 | continue; 55 | } 56 | 57 | size_t offset = (char*)ptr - buffer; 58 | printf("match[%d]: found at %ld, \"%s\", '%c'\n", 59 | i, offset, buffer + offset, buffer[offset]); 60 | 61 | ++found; 62 | buffer[offset] = '\0'; 63 | } 64 | 65 | if (found != sizeof(matches) / sizeof(matches[0])) { 66 | fprintf(stderr, "Not all required matches were found, giving up.\n"); 67 | fprintf(stderr, "(if you run this command more than once, it's good!\n"); 68 | fprintf(stderr, "it means the first run succeeded)\n"); 69 | return 10; 70 | } 71 | 72 | fd = open(argv[1], O_RDWR); 73 | if (fd < 0) { 74 | fprintf(stderr, "Could not open for write %s: %s\n", argv[1], strerror(errno)); 75 | return 3; 76 | } 77 | 78 | data = write(fd, buffer, sizeof(buffer)); 79 | if (data < 0) { 80 | fprintf(stderr, "Could not write %s, good luck: %s\n", argv[1], strerror(errno)); 81 | return 4; 82 | } 83 | 84 | if (close(fd) < 0) { 85 | fprintf(stderr, "Close failed! Good luck: %s - %s\n", argv[1], strerror(errno)); 86 | return 5; 87 | } 88 | 89 | printf("SUCCESS! (maybe! you won't know until you reboot!)\n"); 90 | return 0; 91 | } 92 | -------------------------------------------------------------------------------- /etc/mkinitcpio.conf: -------------------------------------------------------------------------------- 1 | # vim:set ft=sh 2 | # MODULES 3 | # The following modules are loaded before any boot hooks are 4 | # run. Advanced users may wish to specify all system modules 5 | # in this array. For instance: 6 | # MODULES=(piix ide_disk reiserfs) 7 | MODULES=( 8 | sd_mod 9 | ahci 10 | ext4 11 | ) 12 | 13 | # BINARIES 14 | # This setting includes any additional binaries a given user may 15 | # wish into the CPIO image. This is run last, so it may be used to 16 | # override the actual binaries included by a given hook 17 | # BINARIES are dependency parsed, so you may safely ignore libraries 18 | BINARIES=( 19 | fsck 20 | fsck.ext4 21 | ) 22 | 23 | # FILES 24 | # This setting is similar to BINARIES above, however, files are added 25 | # as-is and are not parsed in any way. This is useful for config files. 26 | FILES=() 27 | 28 | # HOOKS 29 | # This is the most important setting in this file. The HOOKS control the 30 | # modules and scripts added to the image, and what happens at boot time. 31 | # Order is important, and it is recommended that you do not change the 32 | # order in which HOOKS are added. Run 'mkinitcpio -H ' for 33 | # help on a given hook. 34 | # 'base' is _required_ unless you know precisely what you are doing. 35 | # 'udev' is _required_ in order to automatically load modules 36 | # 'filesystems' is _required_ unless you specify your fs modules in MODULES 37 | # Examples: 38 | ## This setup specifies all modules in the MODULES setting above. 39 | ## No raid, lvm2, or encrypted root is needed. 40 | # HOOKS=(base) 41 | # 42 | ## This setup will autodetect all modules for your system and should 43 | ## work as a sane default 44 | # HOOKS=(base udev autodetect block filesystems) 45 | # 46 | ## This setup will generate a 'full' image which supports most systems. 47 | ## No autodetection is done. 48 | # HOOKS=(base udev block filesystems) 49 | # 50 | ## This setup assembles a pata mdadm array with an encrypted root FS. 51 | ## Note: See 'mkinitcpio -H mdadm' for more information on raid devices. 52 | # HOOKS=(base udev block mdadm encrypt filesystems) 53 | # 54 | ## This setup loads an lvm2 volume group on a usb device. 55 | # HOOKS=(base udev block lvm2 filesystems) 56 | # 57 | ## NOTE: If you have /usr on a separate partition, you MUST include the 58 | # usr, fsck and shutdown hooks. 59 | HOOKS=( 60 | base 61 | systemd 62 | ) 63 | 64 | # COMPRESSION 65 | # Use this to compress the initramfs image. By default, gzip compression 66 | # is used. Use 'cat' to create an uncompressed image. 67 | #COMPRESSION="gzip" 68 | #COMPRESSION="bzip2" 69 | #COMPRESSION="lzma" 70 | #COMPRESSION="xz" 71 | #COMPRESSION="lzop" 72 | COMPRESSION="lz4" 73 | 74 | # COMPRESSION_OPTIONS 75 | # Additional options for the compressor 76 | COMPRESSION_OPTIONS=(-4) 77 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Faster Arch Linux 2 | 3 | ```sh 4 | sudo cp etc/systemd/journald.conf.d/* /etc/systemd/journald.conf.d # may have to make journald.conf.d 5 | sudo cp etc/logind.conf /etc/systemd/ 6 | sudo cp etc/mkinitcpio.conf /etc/ 7 | sudo cp etc/udev/rules.d/* /etc/udev/rules.d/ # may have to make rules.d 8 | sudo cp etc/makepkg.conf /etc/makepkg.conf 9 | ``` 10 | 11 | 12 | ### Silent Boot 13 | On most modern system the boot time can be decreased by limiting the verbosity of their system to a strict minimum, it is also much more aesthetically pleasing. 14 | 15 | edit /etc/default/grub lines `GRUB_CMDLINE_LINUX` & `GRUB_CMDLINE_LINUX_DEFAULT` 16 | 17 | ```sh 18 | GRUB_CMDLINE_LINUX_DEFAULT="quiet loglevel=3 rd.systemd.show_status=auto rd.udev.log_priority=3 vt.global_cursor_default=0 i915.fastboot=1" 19 | GRUB_CMDLINE_LINUX="quiet loglevel=3 rd.systemd.show_status=auto rd.udev.log_priority=3 vt.global_cursor_default=0 i915.fastboot=1" 20 | ``` 21 | 22 | edit `/etc/sysctl.d/20-quiet-printk.conf` 23 | ```sh 24 | kernel.printk = 3 3 3 3 25 | ``` 26 | 27 | ```sh 28 | systemctl edit --full systemd-fsck-root.service 29 | systemctl edit --full systemd-fsck@.service 30 | ``` 31 | 32 | add these two lines between `ExecStart=/usr/lib/systemd/systemd-fsck` & `TimeoutSec=0` 33 | 34 | ```sh 35 | StandardOutput=null 36 | StandardError=journal+console 37 | ``` 38 | 39 | #### To remove `GRUB loading. Weclome to GRUB!` on boot 40 | ##### Only for systems with efi 41 | ```sh 42 | cd grub-shusher 43 | make 44 | sudo -s 45 | ./grub-kernel /boot/efi/EFI/***/grubx64.efi 46 | ``` 47 | 48 | ### Programs You Can Install 49 | * **preload** - Caches programs you use in RAM to launch faster 50 | * **dbus-broker** - is a drop-in replacement for the libdbus reference implementation, which aims "to provide high performance and reliability, while keeping compatibility to the D-Bus reference implementation". 51 | * **irqbalance** - distribute hardware interrupts across processors on a multiprocessor system in order to increase performance 52 | 53 | 54 | ```sh 55 | sudo pacman -S dbus-broker irqbalance 56 | yay -S preload 57 | 58 | systemctl enable --now dbus-broker.service 59 | systemctl enable --now preload.service 60 | systemctl enable --now irqbalance.service 61 | ``` 62 | 63 | ### Bonus iwd 64 | iwd (iNet wireless daemon) is a wireless daemon for Linux written by Intel that aims to replace WPA supplicant. The core goal of the project is to optimize resource utilization by not depending on any external libraries and instead utilizing features provided by the Linux Kernel to the maximum extent possible. 65 | 66 | iwd can work in standalone mode or in combination with comprehensive network managers like ConnMan, systemd-networkd and NetworkManager. 67 | 68 | In my experience it connects much faster. 69 | 70 | ```sh 71 | sudo pacman -S iwd 72 | systemctl enable --now iwd.service 73 | ``` 74 | 75 | For usage: 76 | * [Standalone](https://wiki.archlinux.org/index.php/Iwd#iwctl) 77 | * [ConnMan](https://wiki.archlinux.org/index.php/ConnMan#Using_iwd_instead_of_wpa_supplicant) 78 | * [NetworkManager](https://wiki.archlinux.org/index.php/NetworkManager#Using_iwd_as_the_Wi-Fi_backend) 79 | 80 | ### Notes 81 | For KDE Desktop Environment Users: 82 | Set splash theme to none -------------------------------------------------------------------------------- /grub-shusher/mbr.c: -------------------------------------------------------------------------------- 1 | #define _GNU_SOURCE 2 | 3 | #include 4 | 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | int main(int argc, char** argv) { 15 | const char* help = 16 | "Usage: ./mbr [-gh] \n" 17 | "\tRequires rw permissions of target file (root, most likely).\n\n" 18 | "\t-g: GPT partition - keep going even if not all patches can be found.\n" 19 | "\t-h (or -v): Print this message\n"; 20 | 21 | bool gpt = false; 22 | int filepos = 0; 23 | 24 | int scanned = 1; 25 | for (; scanned < argc; scanned++) { 26 | /* If this does not start with -, it is not an option, 27 | * it must be the name of the partition. Remember it, 28 | * and keep going. */ 29 | if (*argv[scanned] != '-') { 30 | if (filepos != 0) { 31 | fprintf(stderr, "ERROR: A single partition can be specified.\n%s", help); 32 | return 1; 33 | } 34 | 35 | filepos = scanned; 36 | continue; 37 | } 38 | 39 | /* If this is '--', there are no more options afterward. */ 40 | const char* ptr = argv[scanned] + 1; 41 | if (*ptr == '-' && !*(ptr + 1)) 42 | break; 43 | 44 | /* Scan the actual option argument for flags. */ 45 | for (; *ptr; ptr++) { 46 | switch (*ptr) { 47 | case 'h': 48 | case 'v': 49 | printf(help); 50 | return 0; 51 | 52 | case 'g': 53 | gpt = true; 54 | break; 55 | } 56 | } 57 | } 58 | 59 | /* Either scanning argv did not find the name of the partition, 60 | * or we encountered a --. */ 61 | if (!filepos) { 62 | if ((argc - scanned) != 2) { 63 | fprintf(stderr, "ERROR: You must specify a single" 64 | " file/partition.\n%s", help); 65 | return 1; 66 | } 67 | 68 | filepos = argc - 1; 69 | } 70 | 71 | const char* partition = argv[filepos]; 72 | int fd = open(partition, O_RDONLY); 73 | if (fd < 0) { 74 | fprintf(stderr, "Could not open for read %s: %s\n", 75 | partition, strerror(errno)); 76 | return 1; 77 | } 78 | 79 | printf("opened: %s\n", partition); 80 | 81 | char buffer[1024 * 2]; 82 | int data = read(fd, buffer, sizeof(buffer)); 83 | if (data < 0) { 84 | fprintf(stderr, "Could not read %s: %s\n", 85 | partition, strerror(errno)); 86 | return 2; 87 | } 88 | close(fd); 89 | 90 | printf("read: %d bytes from %s\n", data, partition); 91 | 92 | # define DECLARE_MATCH(str) { str, sizeof(str) - 1 } 93 | struct { 94 | const char* match; 95 | const int length; 96 | } matches[] = { 97 | /* diskboot.S, line ~349 */ 98 | DECLARE_MATCH("loading\0.\0\r\n\0Geom\0Read"), 99 | DECLARE_MATCH(".\0\r\n\0Geom\0Read"), 100 | /* boot.S, line ~391 */ 101 | DECLARE_MATCH("GRUB \0Geom\0Hard Disk\0"), 102 | /* DECLARE_MATCH("Welcome to GRUB!"), */ 103 | }; 104 | 105 | int found = 0; 106 | for (int i = 0; i < sizeof(matches) / sizeof(matches[0]); ++i) { 107 | const char* match = matches[i].match; 108 | const int length = matches[i].length; 109 | 110 | void* ptr = memmem(buffer, data, match, length); 111 | if (!ptr) { 112 | printf("match[%d]: NOT FOUND\n", i); 113 | continue; 114 | } 115 | 116 | size_t offset = (char*)ptr - buffer; 117 | printf("match[%d]: found at %ld, \"%s\", '%c'\n", 118 | i, offset, buffer + offset, buffer[offset]); 119 | 120 | ++found; 121 | buffer[offset] = '\0'; 122 | } 123 | 124 | /* If we did not find all the required matches on a non gpt partition, 125 | * give up immediately, exit with status 10. */ 126 | if (found < (sizeof(matches) / sizeof(matches[0])) && !gpt) { 127 | fprintf(stderr, "Not enough matches were found, giving up.\n"); 128 | fprintf(stderr, "If you have a gpt disk, run this with the -g flag.\n"); 129 | fprintf(stderr, "(if you run this command more than once, it's good!\n"); 130 | fprintf(stderr, "it means the first run succeeded)\n"); 131 | return 10; 132 | } 133 | 134 | /* On GPT partitions, it is ok to have partial matches. Keep going, but 135 | * warn the user about what to do next. */ 136 | if (gpt) { 137 | switch (found) { 138 | case 1: 139 | printf("Found mbr header of gpt disk.\n" 140 | "Make sure to also run this on the ef02 partition of this drive.\n"); 141 | break; 142 | 143 | case 2: 144 | printf("Found ef02 header of gpt grub partition.\n" 145 | "Make sure to also run this on full drive.\n"); 146 | break; 147 | } 148 | } 149 | 150 | fd = open(partition, O_RDWR); 151 | if (fd < 0) { 152 | fprintf(stderr, "Could not open for write %s: %s\n", 153 | partition, strerror(errno)); 154 | return 3; 155 | } 156 | 157 | data = write(fd, buffer, sizeof(buffer)); 158 | if (data < 0) { 159 | fprintf(stderr, "Could not write %s, good luck: %s\n", 160 | partition, strerror(errno)); 161 | return 4; 162 | } 163 | 164 | if (close(fd) < 0) { 165 | fprintf(stderr, "Close failed! Good luck: %s - %s\n", 166 | partition, strerror(errno)); 167 | return 5; 168 | } 169 | 170 | printf("PATCHED SUCCESSFULLY!\n"); 171 | printf("(the message should be gone next time you reboot, good luck!)\n"); 172 | return 0; 173 | } 174 | -------------------------------------------------------------------------------- /grub-shusher/README.md: -------------------------------------------------------------------------------- 1 | What is this? 2 | ============= 3 | 4 | On most systems, GRUB shows a message like 5 | 6 | GRUB loading. 7 | Weclome to GRUB! 8 | 9 | at boot, just before loading the boot menu. Current versions of GRUB 10 | do not provide any mechanism to disable this message without patching 11 | and recompiling GRUB itself. 12 | 13 | This process is cumbersone, as it requires expertise and forces you to 14 | recompile / repatch every time you update grub. 15 | 16 | `grub-shusher` contains two tiny .c files that instead of patching the 17 | grub source code, they patch the grub binaries or installed master boot 18 | record to disable those messages. 19 | 20 | The software is generally safe: it looks for a specific set of patterns, 21 | and if not all are found, it stops processing. It has been tested on a 22 | few machines, and works as expected. 23 | 24 | However, I only have access to a handful of machines, and the code 25 | will modify your master boot record. 26 | 27 | **USE IT AT YOUR OWN RISK - YOU ARE RESPONSIBLE FOR BACKING UP AND RESTORING YOUR DATA** 28 | 29 | At this point, it has been tested on systems with: 30 | 31 | * EFI 32 | * GPT 33 | * Standard partition table 34 | 35 | If you have success / failure stories to tell, please email me 36 | directly (ccontavalli AT gmail.com) or open issues on github 37 | (https://github.com/ccontavalli/grub-shusher/issues). 38 | 39 | 40 | How to use grub-shusher 41 | ======================= 42 | 43 | **REPLACE /dev/sda with your GRUB PARTITION, used with grub-setup or grub-install** 44 | 45 | 46 | On Debian Systems with normal partition table (no EFI, no GPT) 47 | ----------------- 48 | 49 | # ./setup-debian.sh /dev/sda 50 | 51 | ... and go read [configuring grub](#configuring-grub). 52 | 53 | If you want to setup grub-shusher automatically after each upgrade, you 54 | can edit `/etc/apt/apt.conf`, and add a section like: 55 | 56 | DPkg 57 | { 58 | Post-Invoke {"/opt/projects/grub-shusher/setup-debian.sh /dev/sda >/dev/null 2>/dev/null || true;";}; 59 | } 60 | 61 | where `/opt/projects/grub-shuser` is the directory where you downloaded grub-shusher, and `/dev/sda` is 62 | the partition or disk where grub is installed. 63 | 64 | 65 | On Any Other System (TM) with normal partition table (no EFI, no GPT) 66 | ------------------------ 67 | 68 | $ make 69 | $ sudo -s 70 | # ./grub-kernel /boot/grub/kernel.img 71 | # ./grub-kernel /usr/lib/grub/i386-pc/kernel.img 72 | # grub-install /dev/sda 73 | # ./mbr /dev/sda 74 | 75 | 76 | ... and done. Note that the order is important: 77 | 78 | 1. `make` will compile the code, you need to have GCC installed. 79 | 2. `grub-kernel ...` will remove the 'Welcome to GRUB!' message from the `kernel.img` file. 80 | 3. `grub-install /dev/sda` will create a new compressed image 81 | (by merging several other files, including kernel.img) and install it on your disk. 82 | 4. `mbr /dev/sda` will remove a few other messages from the installed mbr. 83 | 84 | ... and go read [configuring grub](#configuring-grub). 85 | 86 | 87 | On Any System (TM) with EFI 88 | ------------------------ 89 | 90 | $ make 91 | $ sudo -s 92 | # ./grub-kernel /boot/efi/EFI/***/grubx64.efi 93 | 94 | ... and done. Important: 95 | 96 | * make always sure that you have made a backup of `grubx64.efi` 97 | 98 | * replace `***` with the distribution name, for example `/boot/efi/EFI/manjaro/grubx64.efi`. 99 | 100 | ... and go read configuring grub. 101 | 102 | 103 | On Any System (TM) with GPT 104 | ------------------------- 105 | 106 | $ make 107 | $ sudo -s 108 | # ./mbr -g /dev/sda 109 | # ./mbr -g /dev/bios-boot-partition 110 | 111 | Note: 112 | 113 | * You must provide the *-g* flag, this is important for GPT partitions. 114 | * You must run `mbr` twice: 115 | 116 | 1. With the partition GRUB was told to use (/dev/sda, in this document). 117 | 2. With the GPT partition, the one marked with the EF02 type. You can 118 | find this partition by running something like: 119 | 120 | # parted /dev/sda print 121 | 122 | 123 | Configuring GRUB 124 | ---------------- 125 | 126 | To make GRUB entirely quiet, my `/etc/defaults/grub` has: 127 | 128 | GRUB_DEFAULT=0 129 | GRUB_TIMEOUT=0 130 | 131 | GRUB_HIDDEN_TIMEOUT=5 132 | GRUB_HIDDEN_TIMEOUT_QUIET=true 133 | 134 | Note that once you have those lines, you need to run `update-grub`, and on next reboot, 135 | you will have to press 'ESC' or keep 'shift' pressed to get into the grub menu. I suggest 136 | you try this before you `shush` grub. 137 | 138 | If something goes wrong, you can: 139 | 140 | # apt-get install --reinstall grub2 141 | # grub-install /dev/sda 142 | 143 | to clean up after yourself. 144 | 145 | You can read more about [grub-shusher on this blog post](http://rabexc.org/posts/grub-shush). 146 | 147 | 148 | Getting back into GRUB 149 | ---------------------- 150 | 151 | Once you change `/etc/defaults/grub` and run `update-grub`, grub will no longer show up at 152 | boot. To get into the menu, you can try two things: 153 | 154 | * Keep `shift` pressed during boot. This is the documented mechanism, did not work for me. 155 | * Press `ESC` at boot. This is a bit tricky, as if you press it too early, most BIOSes 156 | will bring you in the BIOS menu. If you press it too late, well, the operating system 157 | will have booted already. The rule of thumb is to press it at the time the GRUB menu 158 | would have showed up, had it been enabled. If you use the settings above, you have *5* 159 | seconds of window to press the button. On my laptopt, this is right after the screen 160 | is cleared. 161 | 162 | 163 | Contributors and THANKS! 164 | ------------------------ 165 | 166 | Thanks go to: 167 | 168 | * Carlo Contavalli, www.github.com/ccontavalli - main author. 169 | * cybnetsurfe3011, www.github.com/cybnetsurfe3011 - GPT support. 170 | * vincent-t, www.github.com/vincent-t - EFI testing and documentation. 171 | -------------------------------------------------------------------------------- /etc/makepkg.conf: -------------------------------------------------------------------------------- 1 | #!/hint/bash 2 | # 3 | # /etc/makepkg.conf 4 | # 5 | 6 | ######################################################################### 7 | # SOURCE ACQUISITION 8 | ######################################################################### 9 | # 10 | #-- The download utilities that makepkg should use to acquire sources 11 | # Format: 'protocol::agent' 12 | DLAGENTS=('file::/usr/bin/curl -gqC - -o %o %u' 13 | 'ftp::/usr/bin/curl -gqfC - --ftp-pasv --retry 3 --retry-delay 3 -o %o %u' 14 | 'http::/usr/bin/curl -gqb "" -fLC - --retry 3 --retry-delay 3 -o %o %u' 15 | 'https::/usr/bin/curl -gqb "" -fLC - --retry 3 --retry-delay 3 -o %o %u' 16 | 'rsync::/usr/bin/rsync --no-motd -z %u %o' 17 | 'scp::/usr/bin/scp -C %u %o') 18 | 19 | # Other common tools: 20 | # /usr/bin/snarf 21 | # /usr/bin/lftpget -c 22 | # /usr/bin/wget 23 | 24 | #-- The package required by makepkg to download VCS sources 25 | # Format: 'protocol::package' 26 | VCSCLIENTS=('bzr::bzr' 27 | 'git::git' 28 | 'hg::mercurial' 29 | 'svn::subversion') 30 | 31 | ######################################################################### 32 | # ARCHITECTURE, COMPILE FLAGS 33 | ######################################################################### 34 | # 35 | CARCH="x86_64" 36 | CHOST="x86_64-pc-linux-gnu" 37 | 38 | #-- Compiler and Linker Flags 39 | CPPFLAGS="-D_FORTIFY_SOURCE=2" 40 | CFLAGS="-march=native -mtune=skylake -O2 -pipe -fno-plt" 41 | CXXFLAGS="$CFLAGS" 42 | LDFLAGS="-Wl,-O4,--sort-common,--as-needed,-z,relro,-z,now" 43 | #-- Make Flags: change this for DistCC/SMP systems 44 | #MAKEFLAGS="-j2" 45 | #-- Debugging flags 46 | DEBUG_CFLAGS="-g -fvar-tracking-assignments" 47 | DEBUG_CXXFLAGS="-g -fvar-tracking-assignments" 48 | DEBUG_MAKEFLAGS="-j1 --debug=bvij" 49 | #-- CMAKE flags 50 | CMAKE_C_COMPILER="command gcc $CFLAGS" 51 | CMAKE_CXX_COMPILER="command g++ $CXXFLAGS" 52 | CMAKE_LINKER="command ld $LDFLAGS" 53 | ######################################################################### 54 | # BUILD ENVIRONMENT 55 | ######################################################################### 56 | # 57 | # Defaults: BUILDENV=(!distcc !color !ccache check !sign) 58 | # A negated environment option will do the opposite of the comments below. 59 | # 60 | #-- distcc: Use the Distributed C/C++/ObjC compiler 61 | #-- color: Colorize output messages 62 | #-- ccache: Use ccache to cache compilation 63 | #-- check: Run the check() function if present in the PKGBUILD 64 | #-- sign: Generate PGP signature file 65 | # 66 | BUILDENV=(!distcc color !ccache check !sign) 67 | # 68 | #-- If using DistCC, your MAKEFLAGS will also need modification. In addition, 69 | #-- specify a space-delimited list of hosts running in the DistCC cluster. 70 | #DISTCC_HOSTS="" 71 | # 72 | #-- Specify a directory for package building. 73 | #BUILDDIR=/tmp/makepkg 74 | 75 | ######################################################################### 76 | # GLOBAL PACKAGE OPTIONS 77 | # These are default values for the options=() settings 78 | ######################################################################### 79 | # 80 | # Default: OPTIONS=(!strip docs libtool staticlibs emptydirs !zipman !purge !debug) 81 | # A negated option will do the opposite of the comments below. 82 | # 83 | #-- strip: Strip symbols from binaries/libraries 84 | #-- docs: Save doc directories specified by DOC_DIRS 85 | #-- libtool: Leave libtool (.la) files in packages 86 | #-- staticlibs: Leave static library (.a) files in packages 87 | #-- emptydirs: Leave empty directories in packages 88 | #-- zipman: Compress manual (man and info) pages in MAN_DIRS with gzip 89 | #-- purge: Remove files specified by PURGE_TARGETS 90 | #-- debug: Add debugging flags as specified in DEBUG_* variables 91 | # 92 | OPTIONS=(strip docs !libtool !staticlibs emptydirs zipman purge !debug) 93 | 94 | #-- File integrity checks to use. Valid: md5, sha1, sha256, sha384, sha512 95 | INTEGRITY_CHECK=(md5) 96 | #-- Options to be used when stripping binaries. See `man strip' for details. 97 | STRIP_BINARIES="--strip-all" 98 | #-- Options to be used when stripping shared libraries. See `man strip' for details. 99 | STRIP_SHARED="--strip-unneeded" 100 | #-- Options to be used when stripping static libraries. See `man strip' for details. 101 | STRIP_STATIC="--strip-debug" 102 | #-- Manual (man and info) directories to compress (if zipman is specified) 103 | MAN_DIRS=({usr{,/local}{,/share},opt/*}/{man,info}) 104 | #-- Doc directories to remove (if !docs is specified) 105 | DOC_DIRS=(usr/{,local/}{,share/}{doc,gtk-doc} opt/*/{doc,gtk-doc}) 106 | #-- Files to be removed from all packages (if purge is specified) 107 | PURGE_TARGETS=(usr/{,share}/info/dir .packlist *.pod) 108 | #-- Directory to store source code in for debug packages 109 | DBGSRCDIR="/usr/src/debug" 110 | 111 | ######################################################################### 112 | # PACKAGE OUTPUT 113 | ######################################################################### 114 | # 115 | # Default: put built package and cached source in build directory 116 | # 117 | #-- Destination: specify a fixed directory where all packages will be placed 118 | #PKGDEST=/home/packages 119 | #-- Source cache: specify a fixed directory where source files will be cached 120 | #SRCDEST=/home/sources 121 | #-- Source packages: specify a fixed directory where all src packages will be placed 122 | #SRCPKGDEST=/home/srcpackages 123 | #-- Log files: specify a fixed directory where all log files will be placed 124 | #LOGDEST=/home/makepkglogs 125 | #-- Packager: name/email of the person or organization building packages 126 | #PACKAGER="John Doe " 127 | #-- Specify a key to use for package signing 128 | #GPGKEY="" 129 | 130 | ######################################################################### 131 | # COMPRESSION DEFAULTS 132 | ######################################################################### 133 | # 134 | COMPRESSGZ=(gzip -c -f -n --best) 135 | COMPRESSBZ2=(bzip2 -c -f --best) 136 | COMPRESSXZ=(xz -T "$(getconf _NPROCESSORS_ONLN)" -c -z --best -) 137 | COMPRESSLRZ=(lrzip -9 -q) 138 | COMPRESSLZO=(lzop -q --best) 139 | COMPRESSZ=(compress -c -f) 140 | 141 | ######################################################################### 142 | # EXTENSION DEFAULTS 143 | ######################################################################### 144 | # 145 | # WARNING: Do NOT modify these variables unless you know what you are 146 | # doing. 147 | # 148 | PKGEXT='.pkg.tar.xz' 149 | SRCEXT='.src.tar.gz' 150 | --------------------------------------------------------------------------------