1*4882a593Smuzhiyun#!/bin/sh 2*4882a593Smuzhiyun 3*4882a593Smuzhiyun# This scripts makes a minimal bootable SD card image for the Chromebook. 4*4882a593Smuzhiyun# The resulting file is called bootsd.img. It should be written directly 5*4882a593Smuzhiyun# to the card: 6*4882a593Smuzhiyun# 7*4882a593Smuzhiyun# SD=/dev/mmcblk1 # check your device name! 8*4882a593Smuzhiyun# dd if=output/images/bootsd.img of=$SD 9*4882a593Smuzhiyun# 10*4882a593Smuzhiyun# The partitions are created just large enough to hold the kernel and 11*4882a593Smuzhiyun# the rootfs image. Most of the card will be empty, and the secondary 12*4882a593Smuzhiyun# GPT will not be in its proper location. 13*4882a593Smuzhiyun 14*4882a593Smuzhiyun# cgpt does not create protective MBR, and the kernel refuses to read 15*4882a593Smuzhiyun# GPT unless there's some kind of MBR in sector 0. So we need parted 16*4882a593Smuzhiyun# to write that single sector before doing anything with the GPT. 17*4882a593Smuzhiyuncgpt=$HOST_DIR/bin/cgpt 18*4882a593Smuzhiyunparted=$HOST_DIR/sbin/parted 19*4882a593Smuzhiyunkernel=$BINARIES_DIR/uImage.kpart 20*4882a593Smuzhiyunrootfs=$BINARIES_DIR/rootfs.ext2 21*4882a593Smuzhiyun 22*4882a593Smuzhiyunrun() { echo "$@"; "$@"; } 23*4882a593Smuzhiyundie() { echo "$@" >&2; exit 1; } 24*4882a593Smuzhiyuntest -f $kernel || die "No kernel image found" 25*4882a593Smuzhiyuntest -f $rootfs || die "No rootfs image found" 26*4882a593Smuzhiyuntest -x $cgpt || die "cgpt not found (host-vboot-utils have not been built?)" 27*4882a593Smuzhiyun 28*4882a593Smuzhiyun# True file sizes in bytes 29*4882a593Smuzhiyunkernelsize=`stat -t $kernel | cut -d\ -f2` 30*4882a593Smuzhiyunrootfssize=`stat -t $rootfs | cut -d\ -f2` 31*4882a593Smuzhiyun 32*4882a593Smuzhiyun# The card is partitioned in sectors of 8KB. 33*4882a593Smuzhiyun# 4 sectors are reserved for MBR+GPT. Their actual size turns out 34*4882a593Smuzhiyun# to be 33 512-blocks which is just over 2 sectors, but we align 35*4882a593Smuzhiyun# it to a nice round number. 36*4882a593Smuzhiyunsec=8192 37*4882a593Smuzhiyunkernelsec=$(((kernelsize+8191)>>13)) 38*4882a593Smuzhiyunrootfssec=$(((rootfssize+8191)>>13)) 39*4882a593Smuzhiyunheadersec=4 40*4882a593Smuzhiyun 41*4882a593Smuzhiyun# There is also a copy of MBR+GPT at the end of the image. 42*4882a593Smuzhiyun# It's going to be useless but both tools assume it's there. 43*4882a593Smuzhiyunimagesec=$((2*headersec+kernelsec+rootfssec)) 44*4882a593Smuzhiyunbootsd="$BINARIES_DIR/bootsd.img" 45*4882a593Smuzhiyunrun dd bs=$sec count=$imagesec if=/dev/zero of=$bootsd 46*4882a593Smuzhiyun 47*4882a593Smuzhiyun# cgpt needs offsets and sizes in 512-blocks. 48*4882a593Smuzhiyunblock=512 49*4882a593Smuzhiyunkernelstart=$((headersec<<4)) 50*4882a593Smuzhiyunkernelblocks=$((kernelsec<<4)) 51*4882a593Smuzhiyunrootfsblocks=$((rootfssec<<4)) 52*4882a593Smuzhiyunrootfsstart=$((kernelstart+kernelblocks)) 53*4882a593Smuzhiyun 54*4882a593Smuzhiyun# This command initializes both GPT and MBR 55*4882a593Smuzhiyunrun $parted -s $bootsd mklabel gpt 56*4882a593Smuzhiyun 57*4882a593Smuzhiyun# The kernel partition must be marked as bootable, that's why -S -T -P 58*4882a593Smuzhiyunrun $cgpt add -i 1 -b $kernelstart -s $kernelblocks \ 59*4882a593Smuzhiyun -t kernel -l kernel \ 60*4882a593Smuzhiyun -S 1 -T 1 -P 10 $bootsd 61*4882a593Smuzhiyun 62*4882a593Smuzhiyun# It does not really matter where the rootfs partition is located as long 63*4882a593Smuzhiyun# as the kernel can find it. 64*4882a593Smuzhiyun# However, if anything is changed here, kernel.args must be updated as well. 65*4882a593Smuzhiyunrun $cgpt add -i 2 -b $rootfsstart -s $rootfsblocks \ 66*4882a593Smuzhiyun -t data -l rootfs $bootsd 67*4882a593Smuzhiyun 68*4882a593Smuzhiyunrun dd bs=$block if=$kernel of=$bootsd seek=$kernelstart 69*4882a593Smuzhiyunrun dd bs=$block if=$rootfs of=$bootsd seek=$rootfsstart 70