(no commit message)
[reminder] / booting_linux_from_a_loop_file_system.mdwn
1 No general provision seems to exist to boot a Linux system and loop
2 mount as root a file containing a file system, albeit even more
3 complex scenarii, involving the device mapper and its implementations,
4 are supported. It can be useful to have that facility, if
5 repartitioning or using a live CD is not practical. Of course, this
6 makes sense mostly if you don't already run Linux on the target host.
7
8 So in the example below, I will suppose you want to mount a root file
9 system contained in a NTFS file. This NTFS file is part of an
10 underlying Windows machine. Except for the creation of that NTFS
11 file, the rule of the game is to not have to use Windows for the
12 installation step and to not mess with the Windows setup, especially
13 not it's boot process. Booting will happen through an external device
14 (network, CD or USB stick).
15
16 # Similar approaches
17  
18 The above constraint obviously rules out approaches such as
19 [CoLinux](http://www.colinux.org/) and
20 [friends](http://www.topologilinux.com). Other methods which run
21 the installer on Windows such as [Wubi](http://wubi.sourceforge.net) or the [Debian Windows installer](http://en.wikipedia.org/wiki/Win32-loader_(Debian\)) are also out, even if they probably use the
22 same kind of tricks which I will describe below. So this was actually
23 a way for me to learn these!
24
25 # Booting principles
26
27 The current standard way of booting Debian is recalled briefly:
28
29 1. the boot loader (GRUB) loads the kernel image and an initramfs file (line initrd in the GRUB configuration)
30 1. the boot loader uncompresses the kernel and pass control to it
31 1. the initramfs file (a cpio gzipped archive) is uncompressed and mounted as the root file system
32 1. /sbin/init is run and does it's job: essentially loading needed
33 kernel modules which have been prepared inside the initramfs and which
34 are needed for mounting the real root file system, which name is given
35 by kernel options root=
36 1. the real root file system is mounted, presence of initramfs is cleaned up 
37 and control is passed to the /sbin/init there
38
39 More information about initramfs and it's predecessor initrd can be 
40 found on [Wikipedia](http://en.wikipedia.org/wiki/Initrd).
41
42 Our strategy will be to modify the initramfs file system content to be able to 
43 loop mount an NTFS file. But first, you will have to create and populate that file.
44
45 # Installing a Linux root file system in a NTFS file
46
47 The Debian installer has no direct option for that. You could proceed
48 as follows, in case you have only one file system and no swap:
49
50 1. create some big NTFS file, say /somedir/myownrootfs; this is the only step requiring running Windows
51 1. boot a Debian installer CD, and start a shell when asked to define the root partition
52 1. mount the NTFS partition, and create a file system on /somedir/myownrootfs
53 1. exit the shell and continue the installation as normal, naming /somedir/myownrootfs as the root partition and giving the loop option
54 1. at the end of the installation, don't let GRUB write on your NTFS partition
55
56 If you want swap or separate file systems for /usr, /home..., you will have to adapt the above procedure. 
57
58 # Booting in a Linux system whose root file system is a NTFS file
59
60 At that point, your only option to boot in the previously installed
61 system is to run the CD installer in rescue mode, loop mount the NTFS
62 file and pivot_root in it. You will have to do that at least once, as
63 the following procedure requires modifications to some files inside
64 /somedir/myownrootfs, and running a command to generate a new
65 initramfs while the system is live.
66
67 So from now on, I will suppose you have booted in your system as
68 explained just above.
69
70 # initramfs-tools 
71
72 The Debian specific package initramfs-tools contains all that is
73 necessary to manipulate and build the initramfs file. The man page of
74 initramfs-tools explains the organization of the Debian initramfs. In
75 particular, /etc/initramfs-tools is where to put host specific scripts
76 to run inside initramfs, while /usr/share/initramfs-tools contains
77 generic stuff.
78
79 You are encouraged to explore the initramfs file created by the
80 installation process (called like /boot/initrd.img-2.6...) to
81 understand fully how the following works.
82
83 # Modifying initramsfs content
84
85 The root file system is to be given as the root= option for the
86 kernel, normally a partition name. In our case, we need 2 pieces of
87 information: the name of the file containing the root file system and
88 it's NTFS partition name. So we need to add an additional kernel
89 option providing that file name; I will use loop=/somedir/myownrootfs,
90 while the NTFS partition will be called /dev/sdb5.
91
92 This implies editing the GRUB configuration file, for instance the kernel line would  be like:
93     <pre>
94     kernel ... root=/dev/sdb5 loop=/somedir/myownrootfs ...
95     </pre>
96
97 Now the modifications to /etc/initramfs-tools:
98
99 * File /etc/initramfs-tools/modules:
100     <pre>
101     loop
102     ntfs
103     </pre>
104
105 This ensures loop.ko and ntfs.ko are included in initrd.
106
107 * File /etc/initramfs-tools/scripts/init-top/loopboot:
108      <pre>
109      #!/bin/sh     
110      PREREQ=""
111      prereqs()
112      {
113          echo "$PREREQ"
114      }
115      case $1 in
116      # get pre-requisites
117      prereqs)
118          prereqs
119          exit 0
120          ;;
121      esac       
122      [ -d ${rootmnt}2 ] || mkdir --mode=0700 ${rootmnt}2
123      </pre>
124
125 This ensures some intermediate mounting point /root2 is created 
126 (rootmnt having value /root from /sbin/init).
127
128 * File /etc/initramfs-tools/scripts/local-premount/loopboot:
129      <pre>
130      #!/bin/sh      
131      PREREQ=""
132      prereqs()
133      {
134          echo "$PREREQ"
135      }
136      case $1 in
137      # get pre-requisites
138      prereqs)
139          prereqs
140          exit 0
141          ;;
142      esac      
143      modprobe -k ntfs
144      mount -n -t ntfs -o nodiratime,noatime ${ROOT} ${rootmnt}2      
145      modprobe -k loop
146      mount -n -t ext2 -o loop ${rootmnt}2${loop} ${rootmnt}
147      </pre>
148
149 This loop mounts effectively the file from loop= option at the
150 expected point. Notice that I have here hardcoded the file system
151 types. It's certainly possible to autodetect them, but then a larger
152 set of file systems modules are to be included in
153 /etc/initramfs-tools/modules
154
155 # Creating a bootable device
156
157 Now you have to run update-initramfs to get the new
158 initrd.img-2.6... file in place. At that point, if you want to reboot
159 without the installer CD, you have these choices:
160
161 * create a bootable device: USB stick, CD-ROM... including the kernel
162   image and initramfs file; GRUB on that device has to be configured
163   to load it from there
164 * in case of network booting, upload kernel
165   image and initramfs file to another host
166   configured as a bootp or dhcp server.
167
168 Notice how the /boot directory content on /somedir/myownrootfs will
169 never be used when booting; it is only there to feed the booting
170 method just chosen.
171
172 For the sake of completeness, here is how to create an iso for a bootable CD-ROM:
173
174 1. install package grub-rescue; it contains an iso file 
175 /usr/lib/grub-rescue/grub-rescue-cdrom.iso
176 1. mount that iso as e.g. /media/cdrom
177 1. copy all the content of /media/cdrom to a temporary place, e.g. /tmp/newiso, 
178 while keeping the permissions of the files and directories
179 1. you can now unmount /media/cdrom
180 1. in /tmp/newiso, you can remove boot.catalog, but add to it kernel
181   image and initramfs file
182 1. in /tmp/newiso/boot/grub, edit grub.cfg to boot from 
183 the 2 files just added above, which would look like:
184     <pre>
185     menuentry "GNU/Linux" {
186            set root=(cd)
187            linux /vmlinuz root=/dev/sdb5 loop=/somedir/myownrootfs
188            initrd /initrd.img
189     }
190     </pre>
191 1. create a bootable iso with a command like:
192     <pre>
193     genisoimage -o /tmp/new.iso /tmp/newiso
194     </pre>
195 1. burn the iso:
196     <pre>
197     wodim /tmp/new.iso
198     </pre>
199
200 # The moment of truth
201
202 Then, you can reboot with the just burned CD. In case of problems,
203 [use the break= or debug
204 kernel options](http://wiki.debian.org/InitramfsDebug).
205
206 Related links:
207
208 * comparing initramfs with an [alternative](http://wiki.debian.org/InitrdReplacementOptions)
209 * what is said about initramfs by the [Debian competition](http://en.gentoo-wiki.com/wiki/Initramfs)
210 * as noted at the beginning, there is support in initramfs-tools for the 
211 [device mapper](http://linuxgazette.net/114/kapil.html), so
212 a more generic solution to the problem solved here 
213 may involve some work on top of that, such as [dm-loop](http://sources.redhat.com/lvm2/wiki/DMLoop)