Skip to content

Instantly share code, notes, and snippets.

@anatol
Last active August 29, 2015 14:06
Show Gist options
  • Save anatol/dd5ed1b63e542f82c020 to your computer and use it in GitHub Desktop.
Save anatol/dd5ed1b63e542f82c020 to your computer and use it in GitHub Desktop.
Build and update ChromeOS kernel
#!/usr/bin/ruby
require 'fileutils'
REMOTE_ADDR = ARGV[0] || 'ryu'
SRC_DIR = File.expand_path(File.dirname(__FILE__))
WORK_DIR = SRC_DIR + '/work'
KERNEL_FLAGS = 'ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-'
# Build kernel
Dir.chdir(SRC_DIR + '/linux')
unless File.exists?('.config')
system('./chromeos/scripts/prepareconfig chromiumos-arm64')
system("yes '' | #{KERNEL_FLAGS} make oldconfig")
end
FileUtils.mkdir_p(WORK_DIR + '/root/boot')
system("#{KERNEL_FLAGS} make -j6")
system("#{KERNEL_FLAGS} INSTALL_PATH=#{WORK_DIR}/root/boot INSTALL_MOD_PATH=#{WORK_DIR}/root make --silent -j6 modules_install firmware_install")
unless File.exists?(WORK_DIR + '/bootloader.bin')
# arm does not need/have a bootloader in kernel partition
puts "Creating fake bootloader image"
system("dd if=/dev/zero of=#{WORK_DIR}/bootloader.bin bs=512 count=1")
end
# Build kernel image (vmlinux + dtb)
`mkimage -D '-I dts -O dtb -p 1024' -f #{SRC_DIR}/configs/kernel.its #{WORK_DIR}/kernel.img`
# TODO: generate *.its dynamically
# kernel sign keys
# https://chromium.googlesource.com/chromiumos/platform/vboot_reference/+/master/tests/devkeys/kernel.keyblock
# https://chromium.googlesource.com/chromiumos/platform/vboot_reference/+/master/tests/devkeys/kernel_data_key.vbprivk
# sign the kernel. output is kernel.img -> kernel.bin
system("vbutil_kernel --pack #{WORK_DIR}/kernel.bin \
--keyblock #{SRC_DIR}/configs/kernel.keyblock \
--signprivate #{SRC_DIR}/configs/kernel_data_key.vbprivk \
--version 1 \
--config #{SRC_DIR}/configs/config.txt \
--bootloader #{WORK_DIR}/bootloader.bin \
--vmlinuz #{WORK_DIR}/kernel.img \
--arch arm")
FileUtils.cp('System.map', WORK_DIR + '/root/boot')
# Deploy kernel to the board
def remote_sh(cmd)
`ssh #{REMOTE_ADDR} "#{cmd}"`
end
def remote_copy(from, to)
`rsync -a #{from} #{REMOTE_ADDR}:#{to}`
end
def remote_sync_root(to)
for dir in %w(boot lib/modules lib/firmware)
system("rsync -cr --safe-links --delete #{WORK_DIR}/root/#{dir}/ #{REMOTE_ADDR}:#{to}/#{dir}")
end
end
# KERN-B partition 4
# ROOT-B partition 5
device = '/dev/mmcblk0'
kern_part_idx = 4
root_part_idx = 5
new_kernel_part = device + 'p' + kern_part_idx.to_s
new_root_part = device + 'p' + root_part_idx.to_s
# copy and flash kernel
remote_copy("#{WORK_DIR}/kernel.bin", '/tmp/kernel.bin')
remote_sh("dd of=#{new_kernel_part} if=/tmp/kernel.bin bs=4K")
# check if ROOT-B already mounted
current_root = remote_sh('rootdev').strip
# sync modules
if current_root == new_root_part
remote_sh('mount -o remount,rw /')
remote_sync_root('/')
else
remote_new_root = '/tmp/new_root'
remote_sh("mkdir -p #{remote_new_root}")
remote_sh("mount #{new_root_part} #{remote_new_root}")
remote_sync_root(remote_new_root)
remote_sh("mount #{new_root_part}")
end
# mark KERN-B partition boot once
remote_sh("cgpt add -i #{kern_part_idx} -S 0 -T 2 -P 15 #{device}")
old_kernel = remote_sh('uname -r -v')
remote_sh('sync')
#remote_sh('reboot')
puts " = Old kernel: #{old_kernel}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment