Before doing anything, we need to prepare ourselves with the boot process in Ubuntu. For this regard, here is a very helpful article by Aaron Toponce. In summary, Ubuntu will first boot into the S runlevel to excute some critical initializing scripts, then it will switch to runlevel 2. As most other linux distributions, Ubuntu does have 4 multi-user runlevels (2-5), but it only uses 2. Our goal is to revise runlevel 3 to boot to a non-graphical login window, and add an option in grub to start the process.
Step 1. Prepare runlevel 3.
For this non-graphical runlevel, we don't want any thing related to X windows brought up upon boot. Thus, we remove the gdm service script in /etc/rc3.d:
sudo mv /etc/rc3.d/S30gdm /etc/rc3.d/s30gdmNext, Ubuntu has x11-common brought up in the S runlevel, we don't want that in our non-graphical login, so move it to runlevel 2:
sudo mv /etc/rcS.d/S99x11-common /etc/rc2.d/S01x11-common
Step 2. Add a menu item in grub.
The normal way to boot to a desired runlevel is to add a kernel option with a single digits or the letter "S". This is simple in Ubuntu. Open /boot/grub/menu.lst and add this following line:
#altoptions=(non-graphical) quiet 3and update grub menu:
sudo update-grub
Step 3. Tell Ubuntu to go into that runlevel
You don't need this step is you are using a different distribution other than Ubuntu, since the kernel option is automatically recorgnized. In Ubuntu, however, the system use the script /etc/init.d/rc-default to determine next runlevel after the S runlevel. The one shipped with Ubuntu will only boot to runlevel 2 and single user mode. We need to modify this file so that it will accept the kernel runlevel parameter. Just add these lines in /etc/init.d/rc-default before the part testing for "single" in the command line:
# Before testing for single user runlevel in the kernel parameter list, add these lines:And that's it. Now when you power up your computer and there will be a grub menu item to boot your system to non-graphical mode.
RL=`sed -n -e "s/.*[ \t]\([S0-6]\)[ \t].*/\1/p" -e "s/.*[ \t]\([S0-6]\)$/\ 1/p" /proc/cmdline`
if [ 'x'$RL != 'x' ]; then
telinit $RL;
elif ... (following the original script here to test "single" in the cmdline)