5 changes: 5 additions & 0 deletions .gitignore
@@ -1,6 +1,11 @@
version.h
*.o
*.elf
*.elf.debug
build
lpbuild
lp.config*
.xcompile

cscope.*
tags
13 changes: 12 additions & 1 deletion CHANGELOG.md
Expand Up @@ -8,6 +8,16 @@ Releases 4.5.x and 4.6.x are based on mainline support submitted in

## [Unreleased]

## [v4.6.4] - 2017-11-30
### Added
- hidden menu with security registers access for writing the custom serial
number
- `Legacy serial console redirection` option removed
- automated versioning

### Changed
- some code refactoring

## [v4.6.3] - 2017-10-30
### Added
- Enable runtime configuration of UARTc/d, EHCI and mPCIe2 CLK in mainline
Expand Down Expand Up @@ -110,7 +120,8 @@ initial commit based on [coreboot_140908](http://pcengines.ch/tmp/coreboot_14090
### Fixed
- used proper way to access extended SPI registers

[Unreleased]: https://github.com/pcengines/sortbootorder/compare/v4.6.3...master
[Unreleased]: https://github.com/pcengines/sortbootorder/compare/v4.6.4...master
[v4.6.4]: https://github.com/pcengines/sortbootorder/compare/v4.6.3...v4.6.4
[v4.6.3]: https://github.com/pcengines/sortbootorder/compare/v4.5.7...v4.6.3
[v4.5.7]: https://github.com/pcengines/sortbootorder/compare/v4.5.6...v4.5.7
[v4.5.6]: https://github.com/pcengines/sortbootorder/compare/v4.5.5...v4.5.6
Expand Down
149 changes: 88 additions & 61 deletions Makefile
@@ -1,99 +1,126 @@
##
## This file is part of the libpayload project.
## This file is part of the sortbootorder project.
##
## Copyright (C) 2008 Advanced Micro Devices, Inc.
## Copyright (C) 2016 PC Engines GmbH
##
## Redistribution and use in source and binary forms, with or without
## modification, are permitted provided that the following conditions
## are met:
## 1. Redistributions of source code must retain the above copyright
## notice, this list of conditions and the following disclaimer.
## 2. Redistributions in binary form must reproduce the above copyright
## notice, this list of conditions and the following disclaimer in the
## documentation and/or other materials provided with the distribution.
## 3. The name of the author may not be used to endorse or promote products
## derived from this software without specific prior written permission.
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; version 2 of the License.
##
## THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
## ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
## FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
## OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
## HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
## LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
## OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
## SUCH DAMAGE.
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
COREBOOT_REL ?= mainline
COREBOOT_ROOT ?= ../../../..

include $(COREBOOT_ROOT)/.xcompile
# compilation for coreboot mainline (4.5,4.6) or legacy (4.0)
COREBOOT_REL ?= mainline
VERSION ?= $(shell git describe --tags --dirty)

src := $(CURDIR)
# Assuming src path payloads/external/sortbootorder/sortbootorder/ by default
KDIR ?= $(src)/../../../../
srctree := $(src)
build_dir := $(src)/build

LIBCONFIG_PATH := $(realpath $(COREBOOT_ROOT)/payloads/libpayload)
LIBPAYLOAD_DIR := $(build_dir)/libpayload
HAVE_LIBPAYLOAD := $(wildcard $(LIBPAYLOAD_DIR)/lib/libpayload.a)
LIB_CONFIG ?= configs/defconfig-tinycurses
export V := $(V)

CFLAGS := -Wall -Werror -Os -fno-builtin
ifeq ($(COREBOOT_REL),legacy)
CFLAGS += -DCOREBOOT_LEGACY
endif
CONFIG_SHELL := sh
UNAME_RELEASE := $(shell uname -r)
MAKEFLAGS += -rR --no-print-directory

TARGET := sortbootorder
OBJS := $(patsubst %.c,%.o,$(wildcard *.c))
# Make is silent per default, but 'make V=1' will show all compiler calls.
ifneq ($(V),1)
.SILENT:
endif

ARCH-$(CONFIG_LP_ARCH_ARMV) := arm
ARCH-$(CONFIG_LP_ARCH_POWERPC) := powerpc
ARCH-$(CONFIG_LP_ARCH_X86) := x86_32
HOSTCC ?= gcc
HOSTCXX ?= g++
HOSTCFLAGS := -I$(src)
HOSTCXXFLAGS := -I$(src)

LIBPAYLOAD_PATH := $(realpath $(KDIR)/payloads/libpayload)
LIBPAYLOAD_OBJ := $(build_dir)/libpayload
HAVE_LIBPAYLOAD := $(wildcard $(LIBPAYLOAD_OBJ)/lib/libpayload.a)
LIBPAYLOAD_CONFIG ?= configs/defconfig-tinycurses
OBJCOPY ?= objcopy

INCLUDES = -I$(src)/include -I$(KDIR)/src/commonlib/include
SRC_DIRS = spi utils
SRC_FILES = $(wildcard *.c)
SRC_FILES += $(wildcard spi/*.c)
SRC_FILES += $(wildcard utils/*.c)
OBJECTS = $(patsubst %.c,%.o,$(SRC_FILES))
OBJS = $(patsubst %,$(build_dir)/%,$(OBJECTS))
DIRS = $(patsubst %,$(build_dir)/%,$(SRC_DIRS))
TARGET = sortbootorder.elf

all: real-all

# in addition to the dependency below, create the file if it doesn't exist
# to silence warnings about a file that would be generated anyway.
$(if $(wildcard .xcompile),,$(eval $(shell $(KDIR)/util/xcompile/xcompile $(XGCCPATH) > .xcompile || rm -f .xcompile)))
.xcompile: $(KDIR)/util/xcompile/xcompile
$< $(XGCCPATH) > $@.tmp
\mv -f $@.tmp $@ 2> /dev/null || rm -f $@.tmp $@

CONFIG_COMPILER_GCC := y
ARCH-y := x86_32

include .xcompile

CC := $(CC_$(ARCH-y))
AS := $(AS_$(ARCH-y))
OBJCOPY := $(OBJCOPY_$(ARCH-y))

LPCC := CC="$(CC)" $(LIBPAYLOAD_DIR)/bin/lpgcc
LPAS := AS="$(AS)" $(LIBPAYLOAD_DIR)/bin/lpas
LPCC := CC="$(CC)" $(LIBPAYLOAD_OBJ)/bin/lpgcc
LPAS := AS="$(AS)" $(LIBPAYLOAD_OBJ)/bin/lpas

# Make is silent per default, but 'make V=1' will show all compiler calls.
ifneq ($(V),1)
Q := @
CFLAGS += -Wall -Werror -Os -fno-builtin $(CFLAGS_$(ARCH-y)) $(INCLUDES)
ifeq ($(COREBOOT_REL),legacy)
CFLAGS += -DCOREBOOT_LEGACY
endif

all: Makefile $(TARGET).elf
real-all: version $(TARGET)

version:
sed -e "s/@version@/\"$(VERSION)\"/" version.h.in > version.h

$(TARGET): $(OBJS) libpayload $(DIRS)
printf " LPCC $(subst $(CURDIR)/,,$(@)) (LINK)\n"
$(LPCC) -o $@ $(OBJS)
$(OBJCOPY) --only-keep-debug $@ $(TARGET).debug
$(OBJCOPY) --strip-debug $@
$(OBJCOPY) --add-gnu-debuglink=$(TARGET).debug $@

$(TARGET).elf: $(OBJS) libpayload
$(Q)printf " LPCC $(subst $(shell pwd)/,,$(@))\n"
$(Q)$(LPCC) $(CFLAGS) -o $@ $(OBJS)
$(build_dir)/%.o: $(src)/%.c libpayload $(DIRS)
printf " LPCC $(subst $(CURDIR)/,,$(@))\n"
$(LPCC) $(CFLAGS) -c -o $@ $<

%.o: %.c libpayload
$(Q)printf " LPCC $(subst $(shell pwd)/,,$(@))\n"
$(Q)$(LPCC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<
$(DIRS):
mkdir -p $(DIRS)

%.S.o: %.S libpayload
$(Q)printf " LPAS $(subst $(shell pwd)/,,$(@))\n"
$(Q)$(LPAS) $(ASFLAGS) --32 -o $@ $<
defaultbuild:
$(MAKE) all

ifneq ($(strip $(HAVE_LIBPAYLOAD)),)
libpayload:
$(Q)printf "Found Libpayload $(LIBPAYLOAD_DIR).\n"
printf "Found Libpayload $(LIBPAYLOAD_OBJ).\n"
else
LPOPTS=obj="$(CURDIR)/lpbuild" DOTCONFIG="$(CURDIR)/lp.config"
libpayload:
$(Q)printf "Building libpayload @ $(LIBCONFIG_PATH).\n"
$(Q)make -C $(LIBCONFIG_PATH) distclean
$(Q)make -C $(LIBCONFIG_PATH) defconfig KBUILD_DEFCONFIG=$(LIB_CONFIG)
$(Q)make -C $(LIBCONFIG_PATH) DESTDIR=$(build_dir) install
printf "Building libpayload @ $(LIBPAYLOAD_PATH).\n"
$(MAKE) -C $(LIBPAYLOAD_PATH) $(LPOPTS) distclean coreinfo_obj=$(build_dir)/libptmp
$(MAKE) -C $(LIBPAYLOAD_PATH) $(LPOPTS) defconfig KBUILD_DEFCONFIG=$(LIBPAYLOAD_CONFIG)
$(MAKE) -C $(LIBPAYLOAD_PATH) $(LPOPTS) install DESTDIR=$(build_dir)
endif

clean:
$(Q)rm -f $(TARGET).elf $(TARGET).debug *.o
rm -rf *.elf *.elf.debug build/*.o .xcompile

distclean: clean
$(Q)rm -rf $(build_dir)
rm -rf build lpbuild lp.config*

.PHONY: clean distclean

.PHONY: all clean distclean do-it-all depend with-depends without-depends debian postinst
89 changes: 46 additions & 43 deletions README.md
Expand Up @@ -10,16 +10,18 @@ saves boot order in flash.

- [Contents](#contents)
- [Theory of operation](#theory-of-operation)
- [Example menu view](#example-menu-view)
- [Settings description](#settings-description)
- [bootorder file](#bootorder-file)
- [bootorder_map file](#bootorder_map-file)
- [Default settings](#default-settings)
- [BIOS WP option](#bios-wp-option)
- [Example menu view](#example-menu-view)
- [Settings description](#settings-description)
- [bootorder file](#bootorder-file)
- [bootorder_map file](#bootorder_map-file)
- [Default settings](#default-settings)
- [BIOS WP option](#bios-wp-option)
- [Hidden security registers menu](#hidden-security-registers-menu)
- [Example](#example)
- [Building](#building)
- [Manual build](#manual-build)
- [Adding sortbootorder to coreboot.rom file](#adding-sortbootorder-to-corebootrom-file)
- [Recent automated building process](#recent-automated-building-process)
- [Manual build](#manual-build)
- [Adding sortbootorder to coreboot.rom file](#adding-sortbootorder-to-corebootrom-file)
- [Recent automated building process](#recent-automated-building-process)

<!-- /TOC -->

Expand All @@ -29,28 +31,7 @@ saves boot order in flash.

> Exact list may be different, depending on BIOS release version.

For coreboot mainline (4.5.x) version:

```
a USB 1 / USB 2 SS and HS
b SDCARD
c mSATA
d SATA
e mPCIe1 SATA1 and SATA2
f iPXE (disabled)
r Restore boot order defaults
n Network/PXE boot - Currently Disabled
u USB boot - Currently Enabled
l Legacy console redirection - Currently Disabled
w Enable BIOS write protect - Currently Disabled
x Exit setup without save
s Save configuration and exit
```

For coreboot legacy (4.0.x) version:

```
```
a USB 1 / USB 2 SS and HS
b SDCARD
c mSATA
Expand All @@ -62,7 +43,6 @@ For coreboot legacy (4.0.x) version:
r Restore boot order defaults
n Network/PXE boot - Currently Disabled
u USB boot - Currently Enabled
l Legacy console redirection - Currently Enabled
t Serial console - Currently Enabled
o UART C - Currently Enabled
p UART D - Currently Enabled
Expand All @@ -71,9 +51,9 @@ For coreboot legacy (4.0.x) version:
w Enable BIOS write protect - Currently Disabled
x Exit setup without save
s Save configuration and exit
```
```

First part of the list is used to set boot device priorities. Second part of
First part of the list is used to set boot device priorities. Second part of
the list is used to enable/disable specific settings. Those information are
stored in `bootorder` file, which is written back to flash after hitting `s`
key.
Expand Down Expand Up @@ -132,9 +112,9 @@ Relevant content of this file may look like this:
Rest of this file is filled with characters to meet that 4096 bytes
requirement.

When device is attached and detected by `SeaBIOS`, then `SeaBIOS` begins to check
if such device node is written into `bootorder` file. If it is, it gains priority
according to it's place on the list.
When device is attached and detected by `SeaBIOS`, then `SeaBIOS` begins to
check if such device node is written into `bootorder` file. If it is, it gains
priority according to it's place on the list.
You can refer to
[SeaBIOS](https://github.com/pcengines/seabios/blob/coreboot-4.0.x/docs/Runtime_config.md#configuring-boot-order)
documentation for more insight.
Expand Down Expand Up @@ -181,21 +161,44 @@ enabled no writes to flash is possible, including disabling the write protect
option itself and updating the BIOS is also not possible (using e.g. `flashrom`
tool).

### Hidden security registers menu

Experimental menu containing options to write and read serial number to
security registers of the SPI flash chip. To enter press `Z` (`z + shift`)
in the main menu. Option description:

* `r` - reads the stored serial number
* `w {serial}` - writes the serial to register. Saves only first 10 characters.
* `s` - gets lock status of the security registers
* `l {register number}` - try to lock the specified register (1,2 or 3). Serial
is stored in the register 1
* `q` - return to main menu

#### Example

```
> w 1234567890
serial written
> r
serial: 1234567890
> q
```

## Building

### Manual build

> coreboot is in `./coreboot-${BR_NAME}` directory
> coreboot is in `../coreboot-${BR_NAME}` directory

```sh
git clone https://github.com/pcengines/sortbootorder.git sortbootorder
cd sortbootorder
# for mainline coreboot (4.5.x)
COREBOOT_ROOT=../coreboot-${BR_NAME} make distclean
COREBOOT_ROOT=../coreboot-${BR_NAME} make
# for mainline coreboot (4.5.x, 4.6.x)
KDIR=../coreboot-${BR_NAME} make distclean
KDIR=../coreboot-${BR_NAME} make
# for legacy coreboot (4.0.x)
COREBOOT_ROOT=../coreboot-${BR_NAME} make distclean
COREBOOT_ROOT=../coreboot-${BR_NAME} COREBOOT_REL=legacy make
KDIR=../coreboot-${BR_NAME} make distclean
KDIR=../coreboot-${BR_NAME} COREBOOT_REL=legacy make
```

### Adding sortbootorder to coreboot.rom file
Expand Down
21 changes: 21 additions & 0 deletions include/flash_access.h
@@ -0,0 +1,21 @@
#ifndef FLASH_ACCESS_H
#define FLASH_ACCESS_H

#include <stdint.h>

#define MAX_DEVICES 64
#define MAX_LENGTH 64
#define NEWLINE 0x0A
#define NUL 0x00

int init_flash(void);
int is_flash_locked(void);
int lock_flash(void);
int unlock_flash(void);
int read_sec_status(void);
int read_sec(u8 reg, u8 addr, void *buf, size_t len);
int prog_sec(u8 reg, u8 addr, const void *buf, size_t len);
int lock_sec(u8 reg);
void save_flash(int flash_address, char buffer[MAX_DEVICES][MAX_LENGTH], u8 max_lines, u8 spi_wp_toggle);

#endif
6 changes: 6 additions & 0 deletions include/sec_reg_menu.h
@@ -0,0 +1,6 @@
#ifndef SEC_REG_MENU_H
#define SEC_REG_MENU_H

void handle_reg_sec_menu(void);

#endif