Skip to content

Commit

Permalink
Modified error handling
Browse files Browse the repository at this point in the history
Simplified the error handler in mlb, removing the reboot on keypress
and instead just looping a hlt. Rebooting a failed bootloader probably
wouldn't help much, anyway.

Added single-letter error codes to mlb to explain what went wrong.

Moved the version check to the installer. There is no need to check this
at boot time unless the user is doing something very silly.

The above changes have netted a nice 40 b savings in the mlb binary size.

Updated the Readme to reflect the changes.
  • Loading branch information
wikkyk committed Sep 20, 2014
1 parent 4809245 commit 471ca9b
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 31 deletions.
21 changes: 16 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,27 @@ where:
- `<kernel>` is the kernel file to boot
- `<command line>` is the command line to pass to the kernel - don't forget to
pass `root=` as `mlbinstall` will not calculate the root device. Currently
the command line cannot be longer than 40 characters (more just won't fit in
the MBR).
the command line cannot be longer than 80 bytes (more just won't fit in the
MBR).
- `[-vbr]` will make `mlbinstall` ignore the space for the partition table,
giving you more space for the command line. You can safely use it if you're
installing to a Volume Boot Record (partition) and not the Master Boot
Record, e.g. for using with another bootloader in multi-OS setups.
giving you 144 bytes for the command line. You can safely use it if you're
installing to a Volume Boot Record (partition), e.g. for using with another
bootloader in multi-OS setups.

`mlbinstall` is quite noisy if it detects any problems. Restore your MBR from
backup, fix the problems, and try again. If it succeeds, it won't say anything.

Error codes
-----------

If MLB fails to boot your kernel, it will print a one-letter error code.
Currently, there are two error codes:

Error What it means
----- ----------------------------------------
R Failed reading data from disk
M Failed moving data to its final location

Contact
-------

Expand Down
30 changes: 6 additions & 24 deletions mlb.asm
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,6 @@ read_kernel_setup:
mov cx, 0x1000
call read_from_hdd

check_version:

cmp word [es:0x206], 0x204 ; we need protocol version >= 2.04
jb error
test byte [es:0x211], 1
jz error

set_header_fields:

mov byte [es:0x210], 0xe1 ; set type_of_loader
Expand Down Expand Up @@ -149,6 +142,7 @@ read_from_hdd:
mov si, dap
mov dl, 0x80 ; first hard disk
int 0x13
mov al, 'R'
jc error
pop edx
ret
Expand All @@ -162,31 +156,20 @@ do_move:
mov ah, 0x87
mov si, gdt
int 0x15
mov al, 'M'
jc error
pop es
pop edx
ret

error:

mov si, error_msg

msg_loop:

lodsb
and al, al
jz reboot
mov ah, 0xe
mov bx, 7
xor bh, bh
int 0x10
jmp short msg_loop

reboot:

xor ax, ax
int 0x16
int 0x19
jmp 0xf000:0xfff0 ; BIOS reset code
.hlt:
hlt
jmp error.hlt

; Global Descriptor Table

Expand Down Expand Up @@ -223,6 +206,5 @@ dap:
dd 0 ; low bytes of LBA address
dd 0 ; high bytes of LBA address

error_msg db 'err', 0
current_lba dd 0xefbeadde ; mlbinstall replaces this with the kernel LBA
cmd_line db 0
38 changes: 36 additions & 2 deletions mlbinstall.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,25 +19,57 @@
* along with mlbinstall. If not, see <http://www.gnu.org/licenses/>.
*/

#define _BSD_SOURCE
#define _POSIX_C_SOURCE 200809L
#define _XOPEN_SOURCE 500

#include <stdint.h>
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>
#include <err.h>
#include <endian.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <linux/fiemap.h>
#include <linux/fs.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <stdbool.h>
#include <stdio.h>

#include "mlb_bin.h"

/* Checks if the kernel boot protocol is supported */
void check_version(const char *kernel)
{
int fd = open(kernel, O_RDONLY);
if (fd == -1)
err(1, "Failed opening %s", kernel);

long ps = sysconf(_SC_PAGESIZE);
size_t mlength = (512 / ps + 1) * ps;
uint8_t *m = mmap(NULL, mlength, PROT_READ, MAP_PRIVATE, fd, 0);
if (m == MAP_FAILED)
err(1, "Failed mapping %s", kernel);

uint32_t header = *(uint32_t *)(m + 0x202);
uint16_t version = be16toh(*(uint16_t *)(m + 0x206));
uint8_t loadflags = m[0x211];

if (header != 0x53726448)
errx(1, "%s is missing a Linux kernel header", kernel);
if (version < 0x204)
errx(1, "Kernel too old, boot protocol version >= 0x204/\
kernel version >= 2.6.14 required, but %s is 0x%x", kernel, version);
if (!(loadflags & 0x01))
errx(1, "Kernel needs to be loaded high");

munmap(m, mlength);
close(fd);
}

/* Returns the length of cmdline, including the terminating null. */
uint16_t cmdlen(const char *cmdline, size_t mlblen, size_t mbrlen)
{
Expand Down Expand Up @@ -171,6 +203,8 @@ argument to not reserve space for a partition table and gain an extra\n\
const char *kernel = argv[2];
const char *cmdline = argv[3];

check_version(kernel);

size_t mbr_len = vbr ? 510 : 446;
uint16_t cmdline_len = cmdlen(cmdline, mlb_bin_len, mbr_len);
uint32_t kernel_lba = lba(kernel);
Expand Down

0 comments on commit 471ca9b

Please sign in to comment.