1Booting Ubuntu Manually
2-----------------------
3
4This shows a manual approach to booting Ubuntu without standard boot or the EFI
5interface.
6
7As an example of how to set up your boot flow with U-Boot, here are
8instructions for starting Ubuntu from U-Boot. These instructions have been
9tested on Minnowboard MAX with a SATA drive but are equally applicable on
10other platforms and other media. There are really only four steps and it's a
11very simple script, but a more detailed explanation is provided here for
12completeness.
13
14Note: It is possible to set up U-Boot to boot automatically using syslinux.
15It could also use the grub.cfg file (/efi/ubuntu/grub.cfg) to obtain the
16GUID. If you figure these out, please post patches to this README.
17
18Firstly, you will need Ubuntu installed on an available disk. It should be
19possible to make U-Boot start a USB start-up disk but for now let's assume
20that you used another boot loader to install Ubuntu.
21
22Use the U-Boot command line to find the UUID of the partition you want to
23boot. For example our disk is SCSI device 0::
24
25   => part list scsi 0
26
27   Partition Map for SCSI device 0  --   Partition Type: EFI
28
29      Part	Start LBA	End LBA		Name
30        Attributes
31        Type GUID
32        Partition GUID
33      1	0x00000800	0x001007ff	""
34        attrs:	0x0000000000000000
35        type:	c12a7328-f81f-11d2-ba4b-00a0c93ec93b
36        guid:	9d02e8e4-4d59-408f-a9b0-fd497bc9291c
37      2	0x00100800	0x037d8fff	""
38        attrs:	0x0000000000000000
39        type:	0fc63daf-8483-4772-8e79-3d69d8477de4
40        guid:	965c59ee-1822-4326-90d2-b02446050059
41      3	0x037d9000	0x03ba27ff	""
42        attrs:	0x0000000000000000
43        type:	0657fd6d-a4ab-43c4-84e5-0933c84b4f4f
44        guid:	2c4282bd-1e82-4bcf-a5ff-51dedbf39f17
45      =>
46
47This shows that your SCSI disk has three partitions. The really long hex
48strings are called Globally Unique Identifiers (GUIDs). You can look up the
49'type' ones `here`_. On this disk the first partition is for EFI and is in
50VFAT format (DOS/Windows)::
51
52   => fatls scsi 0:1
53               efi/
54
55   0 file(s), 1 dir(s)
56
57
58Partition 2 is 'Linux filesystem data' so that will be our root disk. It is
59in ext2 format::
60
61   => ext2ls scsi 0:2
62   <DIR>       4096 .
63   <DIR>       4096 ..
64   <DIR>      16384 lost+found
65   <DIR>       4096 boot
66   <DIR>      12288 etc
67   <DIR>       4096 media
68   <DIR>       4096 bin
69   <DIR>       4096 dev
70   <DIR>       4096 home
71   <DIR>       4096 lib
72   <DIR>       4096 lib64
73   <DIR>       4096 mnt
74   <DIR>       4096 opt
75   <DIR>       4096 proc
76   <DIR>       4096 root
77   <DIR>       4096 run
78   <DIR>      12288 sbin
79   <DIR>       4096 srv
80   <DIR>       4096 sys
81   <DIR>       4096 tmp
82   <DIR>       4096 usr
83   <DIR>       4096 var
84   <SYM>         33 initrd.img
85   <SYM>         30 vmlinuz
86   <DIR>       4096 cdrom
87   <SYM>         33 initrd.img.old
88   =>
89
90and if you look in the /boot directory you will see the kernel::
91
92   => ext2ls scsi 0:2 /boot
93   <DIR>       4096 .
94   <DIR>       4096 ..
95   <DIR>       4096 efi
96   <DIR>       4096 grub
97            3381262 System.map-3.13.0-32-generic
98            1162712 abi-3.13.0-32-generic
99             165611 config-3.13.0-32-generic
100             176500 memtest86+.bin
101             178176 memtest86+.elf
102             178680 memtest86+_multiboot.bin
103            5798112 vmlinuz-3.13.0-32-generic
104             165762 config-3.13.0-58-generic
105            1165129 abi-3.13.0-58-generic
106            5823136 vmlinuz-3.13.0-58-generic
107           19215259 initrd.img-3.13.0-58-generic
108            3391763 System.map-3.13.0-58-generic
109            5825048 vmlinuz-3.13.0-58-generic.efi.signed
110           28304443 initrd.img-3.13.0-32-generic
111   =>
112
113The 'vmlinuz' files contain a packaged Linux kernel. The format is a kind of
114self-extracting compressed file mixed with some 'setup' configuration data.
115Despite its size (uncompressed it is >10MB) this only includes a basic set of
116device drivers, enough to boot on most hardware types.
117
118The 'initrd' files contain a RAM disk. This is something that can be loaded
119into RAM and will appear to Linux like a disk. Ubuntu uses this to hold lots
120of drivers for whatever hardware you might have. It is loaded before the
121real root disk is accessed.
122
123The numbers after the end of each file are the version. Here it is Linux
124version 3.13. You can find the source code for this in the Linux tree with
125the tag v3.13. The '.0' allows for additional Linux releases to fix problems,
126but normally this is not needed. The '-58' is used by Ubuntu. Each time they
127release a new kernel they increment this number. New Ubuntu versions might
128include kernel patches to fix reported bugs. Stable kernels can exist for
129some years so this number can get quite high.
130
131The '.efi.signed' kernel is signed for EFI's secure boot. U-Boot has its own
132secure boot mechanism - see `this`_ & `that`_. It cannot read .efi files
133at present.
134
135To boot Ubuntu from U-Boot the steps are as follows:
136
1371. Set up the boot arguments. Use the GUID for the partition you want to boot::
138
139   => setenv bootargs root=/dev/disk/by-partuuid/965c59ee-1822-4326-90d2-b02446050059 ro
140
141Here root= tells Linux the location of its root disk. The disk is specified
142by its GUID, using '/dev/disk/by-partuuid/', a Linux path to a 'directory'
143containing all the GUIDs Linux has found. When it starts up, there will be a
144file in that directory with this name in it. It is also possible to use a
145device name here, see later.
146
1472. Load the kernel. Since it is an ext2/4 filesystem we can do::
148
149   => ext2load scsi 0:2 03000000 /boot/vmlinuz-3.13.0-58-generic
150
151The address 30000000 is arbitrary, but there seem to be problems with using
152small addresses (sometimes Linux cannot find the ramdisk). This is 48MB into
153the start of RAM (which is at 0 on x86).
154
1553. Load the ramdisk (to 64MB)::
156
157   => ext2load scsi 0:2 04000000 /boot/initrd.img-3.13.0-58-generic
158
1594. Start up the kernel. We need to know the size of the ramdisk, but can use
160   a variable for that. U-Boot sets 'filesize' to the size of the last file it
161   loaded::
162
163   => zboot 03000000 0 04000000 ${filesize}
164
165Type 'help zboot' if you want to see what the arguments are. U-Boot on x86 is
166quite verbose when it boots a kernel. You should see these messages from
167U-Boot::
168
169   Valid Boot Flag
170   Setup Size = 0x00004400
171   Magic signature found
172   Using boot protocol version 2.0c
173   Linux kernel version 3.13.0-58-generic (buildd@allspice) #97-Ubuntu SMP Wed Jul 8 02:56:15 UTC 2015
174   Building boot_params at 0x00090000
175   Loading bzImage at address 100000 (5805728 bytes)
176   Magic signature found
177   Initial RAM disk at linear address 0x04000000, size 19215259 bytes
178   Kernel command line: "root=/dev/disk/by-partuuid/965c59ee-1822-4326-90d2-b02446050059 ro"
179
180   Starting kernel ...
181
182U-Boot prints out some bootstage timing. This is more useful if you put the
183above commands into a script since then it will be faster::
184
185   Timer summary in microseconds:
186          Mark    Elapsed  Stage
187             0          0  reset
188       241,535    241,535  board_init_r
189     2,421,611  2,180,076  id=64
190     2,421,790        179  id=65
191     2,428,215      6,425  main_loop
192    48,860,584 46,432,369  start_kernel
193
194   Accumulated time:
195                  240,329  ahci
196                1,422,704  vesa display
197
198Now the kernel actually starts (if you want to examine kernel boot up message on
199the serial console, append "console=ttyS0,115200" to the kernel command line)::
200
201   [    0.000000] Initializing cgroup subsys cpuset
202   [    0.000000] Initializing cgroup subsys cpu
203   [    0.000000] Initializing cgroup subsys cpuacct
204   [    0.000000] Linux version 3.13.0-58-generic (buildd@allspice) (gcc version 4.8.2 (Ubuntu 4.8.2-19ubuntu1) ) #97-Ubuntu SMP Wed Jul 8 02:56:15 UTC 2015 (Ubuntu 3.13.0-58.97-generic 3.13.11-ckt22)
205   [    0.000000] Command line: root=/dev/disk/by-partuuid/965c59ee-1822-4326-90d2-b02446050059 ro console=ttyS0,115200
206
207It continues for a long time. Along the way you will see it pick up your
208ramdisk::
209
210   [    0.000000] RAMDISK: [mem 0x04000000-0x05253fff]
211   ...
212   [    0.788540] Trying to unpack rootfs image as initramfs...
213   [    1.540111] Freeing initrd memory: 18768K (ffff880004000000 - ffff880005254000)
214   ...
215
216Later it actually starts using it::
217
218   Begin: Running /scripts/local-premount ... done.
219
220You should also see your boot disk turn up::
221
222   [    4.357243] scsi 1:0:0:0: Direct-Access     ATA      ADATA SP310      5.2  PQ: 0 ANSI: 5
223   [    4.366860] sd 1:0:0:0: [sda] 62533296 512-byte logical blocks: (32.0 GB/29.8 GiB)
224   [    4.375677] sd 1:0:0:0: Attached scsi generic sg0 type 0
225   [    4.381859] sd 1:0:0:0: [sda] Write Protect is off
226   [    4.387452] sd 1:0:0:0: [sda] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
227   [    4.399535]  sda: sda1 sda2 sda3
228
229Linux has found the three partitions (sda1-3). Mercifully it doesn't print out
230the GUIDs. In step 1 above we could have used::
231
232   setenv bootargs root=/dev/sda2 ro
233
234instead of the GUID. However if you add another drive to your board the
235numbering may change whereas the GUIDs will not. So if your boot partition
236becomes sdb2, it will still boot. For embedded systems where you just want to
237boot the first disk, you have that option.
238
239The last thing you will see on the console is mention of plymouth (which
240displays the Ubuntu start-up screen) and a lot of 'Starting' messages::
241
242   * Starting Mount filesystems on boot                                   [ OK ]
243
244After a pause you should see a login screen on your display and you are done.
245
246If you want to put this in a script you can use something like this::
247
248   setenv bootargs root=UUID=b2aaf743-0418-4d90-94cc-3e6108d7d968 ro
249   setenv boot zboot 03000000 0 04000000 \${filesize}
250   setenv bootcmd "ext2load scsi 0:2 03000000 /boot/vmlinuz-3.13.0-58-generic; ext2load scsi 0:2 04000000 /boot/initrd.img-3.13.0-58-generic; run boot"
251   saveenv
252
253The \ is to tell the shell not to evaluate ${filesize} as part of the setenv
254command.
255
256You can also bake this behaviour into your build by hard-coding the
257environment variables if you add this to minnowmax.h:
258
259.. code-block:: c
260
261	#undef CONFIG_BOOTCOMMAND
262	#define CONFIG_BOOTCOMMAND	\
263		"ext2load scsi 0:2 03000000 /boot/vmlinuz-3.13.0-58-generic; " \
264		"ext2load scsi 0:2 04000000 /boot/initrd.img-3.13.0-58-generic; " \
265		"run boot"
266
267	#undef CFG_EXTRA_ENV_SETTINGS
268	#define CFG_EXTRA_ENV_SETTINGS "boot=zboot 03000000 0 04000000 ${filesize}"
269
270and change CONFIG_BOOTARGS value in configs/minnowmax_defconfig to::
271
272   CONFIG_BOOTARGS="root=/dev/sda2 ro"
273
274.. _here: https://en.wikipedia.org/wiki/GUID_Partition_Table
275.. _this: http://events.linuxfoundation.org/sites/events/files/slides/chromeos_and_diy_vboot_0.pdf
276.. _that: http://events.linuxfoundation.org/sites/events/files/slides/elce-2014.pdf
277