Grub Rescue on Mac after Partition Resize

178

There are a number of possible solutions, but it's hard to say what will work best, since it's unclear how Linux is installed (BIOS mode or EFI mode), although my guess is you've got a BIOS-mode installation.

One possible quick fix is to run update-grub within Ubuntu. If successful, this will update the GRUB files, thus restoring it to proper functionality. If unsuccessful, though, this could make matters worse, possibly making it impossible to boot Linux in the way you're doing it now.

Another option is a bit more complex, and is more likely to work, but is still not without risks:

  1. In Linux, type df / and take note of the device filename associated with /. It's probably /dev/sda3, /dev/sda4, or some other numbered partition.
  2. In OS X, download and install rEFInd.
  3. In OS X, install the EFI filesystem driver for whatever filesystem you use on your Linux root (/) filesystem (or on /boot, if it's separate). rEFInd ships with drivers for ext2/3fs, ext4fs, and ReiserFS. You install a filesystem driver by copying it to the drivers or drivers_x64 subdirectory of the rEFInd installation directory (normally /EFI/refind).
  4. Reboot. rEFInd should appear.
  5. Highlight one of the vmlinuz-{version} options on the menu and hit F2 or Insert twice. This should open a simple line editor.
  6. Add ro root=/dev/sda3 to the options, changing /dev/sda3 to the partition you identified in the first step.
  7. Hit Enter. Linux should boot.
  8. Locate the mkrlconf.sh script that came with rEFInd and run it. This should create a file called /boot/refind_linux.conf, which will obviate the need to add kernel options (steps 5-6) when you boot Linux the next time; just hitting Enter should do the trick.

This procedure bypasses GRUB and is likely to be more robust than GRUB in the long term; however, some Macs don't work well when booted directly in EFI mode (as this solution does), so it's conceivable that it won't be an acceptable option for you. If so, you'll need to get a BIOS-mode version of GRUB (or some other boot loader) working. You may also need to clean up your boot menu. Consult the rEFInd documentation for refind.conf, paying particular attention to the dont_scan_dirs, dont_scan_files, and scanfor options, for details on how to do this. Deleting files (such as the refit.efi file) can also do the trick.

Share:
178

Related videos on Youtube

Ruben Rizzi
Author by

Ruben Rizzi

Updated on September 18, 2022

Comments

  • Ruben Rizzi
    Ruben Rizzi over 1 year

    I installed Yeoman with angular generator, and it created Gruntfile.js. The problem is that after launching the webserver in the terminal with:

    grunt serve
    

    Yeoman generates main.css with in the end the reference of the source map

    /*# sourceMappingURL=main.css.map */
    

    But after changing any scss the watch routine regenerates it without the reference of the source map in the end.

    You can see my Gruntfile.js attached below:

        // Generated on 2015-06-16 using generator-angular 0.11.1
        'use strict';
    
        // # Globbing
        // for performance reasons we're only matching one level down:
        // 'test/spec/{,*/}*.js'
        // use this if you want to recursively match all subfolders:
        // 'test/spec/**/*.js'
    
        module.exports = function (grunt) {
    
          // Load grunt tasks automatically
          require('load-grunt-tasks')(grunt);
    
          // Time how long tasks take. Can help when optimizing build times
          require('time-grunt')(grunt);
    
          // Configurable paths for the application
          var appConfig = {
            app: require('./bower.json').appPath || 'app',
            dist: 'dist'
          };
    
          // Define the configuration for all the tasks
          grunt.initConfig({
    
            // Project settings
            yeoman: appConfig,
    
            // Watches files for changes and runs tasks based on the changed files
            watch: {
              bower: {
                files: ['bower.json'],
                tasks: ['wiredep']
              },
              js: {
                files: ['<%= yeoman.app %>/scripts/{,*/}*.js'],
                tasks: ['newer:jshint:all'],
                options: {
                  livereload: '<%= connect.options.livereload %>'
                }
              },
              jsTest: {
                files: ['test/spec/{,*/}*.js'],
                tasks: ['newer:jshint:test', 'karma']
              },
              sass: {
                files: ['<%= yeoman.app %>/styles/{,*/}*.{scss,sass}'],
                tasks: ['sass:server', 'autoprefixer']
              },
              gruntfile: {
                files: ['Gruntfile.js']
              },
              livereload: {
                options: {
                  livereload: '<%= connect.options.livereload %>'
                },
                files: [
                  '<%= yeoman.app %>/{,*/}*.html',
                  '.tmp/styles/{,*/}*.css',
                  '<%= yeoman.app %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}'
                ]
              }
            },
    
            // The actual grunt server settings
            connect: {
              options: {
                port: 9000,
                // Change this to '0.0.0.0' to access the server from outside.
                hostname: 'localhost',
                livereload: 35729
              },
              livereload: {
                options: {
                  open: true,
                  middleware: function (connect) {
                    return [
                      connect.static('.tmp'),
                      connect().use(
                        '/bower_components',
                        connect.static('./bower_components')
                      ),
                      connect().use(
                        '/app/styles',
                        connect.static('./app/styles')
                      ),
                      connect.static(appConfig.app)
                    ];
                  }
                }
              },
              test: {
                options: {
                  port: 9001,
                  middleware: function (connect) {
                    return [
                      connect.static('.tmp'),
                      connect.static('test'),
                      connect().use(
                        '/bower_components',
                        connect.static('./bower_components')
                      ),
                      connect.static(appConfig.app)
                    ];
                  }
                }
              },
              dist: {
                options: {
                  open: true,
                  base: '<%= yeoman.dist %>'
                }
              }
            },
    
            // Make sure code styles are up to par and there are no obvious mistakes
            jshint: {
              options: {
                jshintrc: '.jshintrc',
                reporter: require('jshint-stylish')
              },
              all: {
                src: [
                  'Gruntfile.js',
                  '<%= yeoman.app %>/scripts/{,*/}*.js'
                ]
              },
              test: {
                options: {
                  jshintrc: 'test/.jshintrc'
                },
                src: ['test/spec/{,*/}*.js']
              }
            },
    
            // Empties folders to start fresh
            clean: {
              dist: {
                files: [{
                  dot: true,
                  src: [
                    '.tmp',
                    '<%= yeoman.dist %>/{,*/}*',
                    '!<%= yeoman.dist %>/.git{,*/}*'
                  ]
                }]
              },
              server: '.tmp'
            },
    
            // Add vendor prefixed styles
            autoprefixer: {
              options: {
                browsers: ['last 1 version']
              },
              server: {
                options: {
                  map: true,
                },
                files: [{
                  expand: true,
                  cwd: '.tmp/styles/',
                  src: '{,*/}*.css',
                  dest: '.tmp/styles/'
                }]
              },
              dist: {
                files: [{
                  expand: true,
                  cwd: '.tmp/styles/',
                  src: '{,*/}*.css',
                  dest: '.tmp/styles/'
                }]
              }
            },
    
            // Automatically inject Bower components into the app
            wiredep: {
              app: {
                src: ['<%= yeoman.app %>/index.html'],
                ignorePath:  /\.\.\//
              },
              test: {
                devDependencies: true,
                src: '<%= karma.unit.configFile %>',
                ignorePath:  /\.\.\//,
                fileTypes:{
                  js: {
                    block: /(([\s\t]*)\/{2}\s*?bower:\s*?(\S*))(\n|\r|.)*?(\/{2}\s*endbower)/gi,
                      detect: {
                        js: /'(.*\.js)'/gi
                      },
                      replace: {
                        js: '\'{{filePath}}\','
                      }
                    }
                  }
              },
              sass: {
                src: ['<%= yeoman.app %>/styles/{,*/}*.{scss,sass}'],
                ignorePath: /(\.\.\/){1,2}bower_components\//
              }
            },
    
            // Compiles Sass to CSS
            sass: {
              options: {
                includePaths: [
                  'bower_components'
                ],
                sourceMap: true,
              },
              dist: {
                files: [{
                  expand: true,
                  cwd: '<%= yeoman.app %>/styles',
                  src: ['*.scss'],
                  dest: '.tmp/styles',
                  ext: '.css'
                }]
              },
              server: {
                files: [{
                  expand: true,
                  cwd: '<%= yeoman.app %>/styles',
                  src: ['*.scss'],
                  dest: '.tmp/styles',
                  ext: '.css'
                }]
              } 
            },
    
            // Renames files for browser caching purposes
            filerev: {
              dist: {
                src: [
                  '<%= yeoman.dist %>/scripts/{,*/}*.js',
                  '<%= yeoman.dist %>/styles/{,*/}*.css',
                  '<%= yeoman.dist %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}',
                  '<%= yeoman.dist %>/styles/fonts/*'
                ]
              }
            },
    
            // Reads HTML for usemin blocks to enable smart builds that automatically
            // concat, minify and revision files. Creates configurations in memory so
            // additional tasks can operate on them
            useminPrepare: {
              html: '<%= yeoman.app %>/index.html',
              options: {
                dest: '<%= yeoman.dist %>',
                flow: {
                  html: {
                    steps: {
                      js: ['concat', 'uglifyjs'],
                      css: ['cssmin']
                    },
                    post: {}
                  }
                }
              }
            },
    
            // Performs rewrites based on filerev and the useminPrepare configuration
            usemin: {
              html: ['<%= yeoman.dist %>/{,*/}*.html'],
              css: ['<%= yeoman.dist %>/styles/{,*/}*.css'],
              options: {
                assetsDirs: [
                  '<%= yeoman.dist %>',
                  '<%= yeoman.dist %>/images',
                  '<%= yeoman.dist %>/styles'
                ]
              }
            },
    
            // The following *-min tasks will produce minified files in the dist folder
            // By default, your `index.html`'s <!-- Usemin block --> will take care of
            // minification. These next options are pre-configured if you do not wish
            // to use the Usemin blocks.
            // cssmin: {
            //   dist: {
            //     files: {
            //       '<%= yeoman.dist %>/styles/main.css': [
            //         '.tmp/styles/{,*/}*.css'
            //       ]
            //     }
            //   }
            // },
            // uglify: {
            //   dist: {
            //     files: {
            //       '<%= yeoman.dist %>/scripts/scripts.js': [
            //         '<%= yeoman.dist %>/scripts/scripts.js'
            //       ]
            //     }
            //   }
            // },
            // concat: {
            //   dist: {}
            // },
    
            imagemin: {
              dist: {
                files: [{
                  expand: true,
                  cwd: '<%= yeoman.app %>/images',
                  src: '{,*/}*.{png,jpg,jpeg,gif}',
                  dest: '<%= yeoman.dist %>/images'
                }]
              }
            },
    
            svgmin: {
              dist: {
                files: [{
                  expand: true,
                  cwd: '<%= yeoman.app %>/images',
                  src: '{,*/}*.svg',
                  dest: '<%= yeoman.dist %>/images'
                }]
              }
            },
    
            htmlmin: {
              dist: {
                options: {
                  collapseWhitespace: true,
                  conservativeCollapse: true,
                  collapseBooleanAttributes: true,
                  removeCommentsFromCDATA: true,
                  removeOptionalTags: true
                },
                files: [{
                  expand: true,
                  cwd: '<%= yeoman.dist %>',
                  src: ['*.html', 'views/{,*/}*.html'],
                  dest: '<%= yeoman.dist %>'
                }]
              }
            },
    
            // ng-annotate tries to make the code safe for minification automatically
            // by using the Angular long form for dependency injection.
            ngAnnotate: {
              dist: {
                files: [{
                  expand: true,
                  cwd: '.tmp/concat/scripts',
                  src: '*.js',
                  dest: '.tmp/concat/scripts'
                }]
              }
            },
    
            // Replace Google CDN references
            cdnify: {
              dist: {
                html: ['<%= yeoman.dist %>/*.html']
              }
            },
    
            // Copies remaining files to places other tasks can use
            copy: {
              dist: {
                files: [{
                  expand: true,
                  dot: true,
                  cwd: '<%= yeoman.app %>',
                  dest: '<%= yeoman.dist %>',
                  src: [
                    '*.{ico,png,txt}',
                    '.htaccess',
                    '*.html',
                    'views/{,*/}*.html',
                    'images/{,*/}*.{webp}',
                    'styles/fonts/{,*/}*.*'
                  ]
                }, {
                  expand: true,
                  cwd: '.tmp/images',
                  dest: '<%= yeoman.dist %>/images',
                  src: ['generated/*']
                }, {
                  expand: true,
                  cwd: '.',
                  src: 'bower_components/bootstrap-sass-official/assets/fonts/bootstrap/*',
                  dest: '<%= yeoman.dist %>'
                }]
              },
              styles: {
                expand: true,
                cwd: '<%= yeoman.app %>/styles',
                dest: '.tmp/styles/',
                src: '{,*/}*.css'
              }
            },
    
            // Run some tasks in parallel to speed up the build process
            concurrent: {
              server: [
                'sass:server',
                'copy:styles'
              ],
              test: [
                'copy:styles'
              ],
              dist: [
                'sass',
                'copy:styles',
                'imagemin',
                'svgmin'
              ]
            },
    
            // Test settings
            karma: {
              unit: {
                configFile: 'test/karma.conf.js',
                singleRun: true
              }
            }
          });
    
    
          grunt.registerTask('serve', 'Compile then start a connect web server', function (target) {
            if (target === 'dist') {
              return grunt.task.run(['build', 'connect:dist:keepalive']);
            }
    
            grunt.task.run([
              'clean:server',
              'wiredep',
              'concurrent:server',
              'autoprefixer:server',
              'connect:livereload',
              'watch'
            ]);
          });
    
          grunt.registerTask('server', 'DEPRECATED TASK. Use the "serve" task instead', function (target) {
            grunt.log.warn('The `server` task has been deprecated. Use `grunt serve` to start a server.');
            grunt.task.run(['serve:' + target]);
          });
    
          grunt.registerTask('test', [
            'clean:server',
            'wiredep',
            'concurrent:test',
            'autoprefixer',
            'connect:test',
            'karma'
          ]);
    
          grunt.registerTask('build', [
            'clean:dist',
            'wiredep',
            'useminPrepare',
            'concurrent:dist',
            'autoprefixer',
            'concat',
            'ngAnnotate',
            'copy:dist',
            'cdnify',
            'cssmin',
            'uglify',
            'filerev',
            'usemin',
            'htmlmin'
          ]);
    
          grunt.registerTask('default', [
            'newer:jshint',
            'test',
            'build',
            'sass'
          ]);
        };
    
    • Amit
      Amit almost 11 years
      Ok, this might be a start: mennucc1.debian.net/macbook_linux_efi.html
    • Amit
      Amit almost 11 years
      Tried the steps in this link, here's what I got; new badge in rEFIt when booting, selecting it leads to grub menu, selecting option in this grub menu led either to a black screen or weird graphics depending on the insmod option in the load_video function in grub.cfg. Meanwhile, this broke the former linux badge in rEFIt, which now leads to a black screen with a blinking prompt, and no grub rescue anymore.
    • fontophilic
      fontophilic almost 9 years
      I didn't spot any errors in your file, but here was something that confused me at first: the default yeoman grunt serve doesn't actually generate a css in a styles folder. It creates a temp cashed css. "real" css gets built when you do a $ grunt build.
  • Amit
    Amit almost 11 years
    First of all, thank you so much for your help!! :) I'm going to try the steps you suggested (I think you're right for the BIOS mode for the Linux installation), but if it can be of any help, here is what happened since the OP:
  • Amit
    Amit almost 11 years
    I first tried to boot from a live CD, chroot into my Ubuntu partition, and run a grub-install with two options (root-directory and recheck I think); the command exited with an error saying something about "not GPT something" and that I could use "blocklists" instead but that they were unsafe.
  • Amit
    Amit almost 11 years
    Then I tried what was suggested in the link I posted as a comment of the OP. The result is the second comment. Then I booted again from a live CD, chrooted in my Ubuntu partition, purged grub-efi-amd64, cleanded the grub directory out of the EFI partition (/dev/sda1), and ran update-grub2. The result is that I deleted the "new" badge in rEFIt menu (normal), but the old one still leads to a black screen with blinking prompt. In short; I think I made things worse :/
  • Ruben Rizzi
    Ruben Rizzi almost 9 years
    Wow thank you! It is working and the explanation is clear! +1