It is widely known you need initrd or initramfs to boot your Linux box over USB media, namely USB HDD or Flash memory drives, but you can do it without it.
Basically, USB media relies on SCSI driver for its recognition. The problem is that you have to wait for some time to make it recognized, namely one or two seconds or so. And during the time your kernel doesn’t wait for the media to be recognized - yes. it was the “common sense.”
However, you can make your Linux kernel to wait for root devices to be recognized. Simply add “rootwait” option on your kernel boot parameter and everything is done. Or, you can use “rootdelay=NN” option to make some timeout. These options are introduced in kernel 2.6, and I heard that there’s a patch for 2.4 kernels to do the same.
The only problem here is that you can’t make use of UUID or disk labels to recognize the boot media. Dynamic devfs like mdev or udev need to be run to assign UUIDs or read disk labels from each partition. So, chances are that you must rely on traditional static devfs - boot to /dev/sda or so.
Of course there’s a issue that you do may not know which device file is assigned to your boot media on boot. Your /dev/sda can be either SATA or SAS HDD, and there can be more than one - chances are, most of the time your boot media can be assigned as /dev/sdb or sdc or sdd or….. Whatever. In this case, you can compile your kernel to include only SCSI disk driver and USB media only and compile others(SATA, SAS, IDE…..) as modules so that during the initial boot kernel can recognize only USB media and other media can be recognized later on init stage when udev or mdev is populated(=daemon is started).
Hope this helps you simplifying your boot process of Linux from USB media. Good luck!
A blog from a software developer who didn't get any formal training or education at all. :P
Sunday, April 22, 2012
How to boot your Linux box on USB media without initrd or initramfs
initrd나 initramfs 없이 리눅스를 USB에서 부팅하기
일반적으로 리눅스를 USB에서 부팅하려면 initrd나 initramfs를 필수적으로 사용해야 되는 것으로 알려져 있습니다만, 실제로는 필요가 없게 만들 수도 있습니다.
기본적으로 USB는 SCSI 드라이버를 통해 자신을 인식합니다. 단지 문제라면, USB 미디어는 커널이 그 존재를 인식하는데 시간이 걸린다는 겁니다(일반적으로 1~2초). 그리고 커널은 그 시간을 기다려주지 않고 무작정 지 멋대로 부팅하다가 부팅할 미디어가 없다면서 멈춰버리죠.
하지만, 커널 2.6에서 추가된 rootwait이나 rootdelay=NN 커널 부팅 옵션을 사용하면 root device가 부팅할 때까지 커널을 기다리게 할 수 있습니다. 무작정 기다리려면 rootwait을, 타임아웃이 필요하다면 rootdelay를 사용하면 됩니다(※Kernel 2.4에서는 이와 관련된 별도의 패치가 필요하다고 합니다).
단지, 한가지 문제점이 있다면, 이런 방법으로는 UUID나 디스크 레이블로 부팅 미디어를 지정할 수 없다는 것입니다. UUID나 디스크 레이블은 mdev나 udev같은 동적 디바이스 파일시스템을 사용하는데, 이를 동작시키려면 initrd나 initramfs가 필요합니다 - 뒤집어서 말하자면, 이 방법을 사용하면 정적인 구형 devfs를 사용하는 방법밖에 없습니다. 이를테면, /dev/sda같은 형태로밖에 부팅 디바이스를 지정할 수 없습니다.
이렇게 되면 가끔은 부팅할 디바이스의 디바이스 파일이 무엇으로 설정될지 감을 잡을 수 없는 경우가 생깁니다. /dev/sda는 SATA나 SAS가 될 수도 있고, 시스템에 따라 1개가 아니라 그 이상의 HDD가 달려있을 수도 있습니다. 이게 sdb가 될지 sdc가 될지 sdd가 될지 뭐가 될지 며느리도 모르는 상황이 될 수도 있다는 거죠(……).
이 경우 편법을 사용하는 방법이 있습니다. SCSI 디스크 드라이버와 USB media 드라이버만 커널에 포함시키고, 나머지, 그러니까 SATA나 SAS, IDE같은 것들은 모듈로 컴파일해서 udev나 mdev가 동작할 때쯤 인식시키게 하면 커널은 무조건 USB 미디어부터 인식하게 됩니다. 이렇게 하면, USB 미디어가 2개 이상이 되지 않는 한, USB는 무조건 /dev/sda로 인식됩니다.
다들 잘 아시는 방법이시겠지만, 혹시나 모르시는 분들이 있을까봐(사실은 제가 잊어버릴까봐) 이 포스팅에 올려둡니다. 이 방법이 우연히 여기를 방문하시는 분들이 USB로 리눅스를 부팅하는 프로세스를 단순화하는데 도움이 되었으면 합니다.
Sunday, April 15, 2012
Order of Rebuilding Complete Toolchain in Linux
First update Linux header files and toolchain components once in following order: linux-header glibc binutils gcc
Now upgrade is made, but still the machine codes are from legacy toolchains. So we’re urged to renew the machine code of toolchain components themselves.
One note: in Gentoo Linux, you have to run gcc-config to check whether the new version is selected as the default compiler, or your Gentoo box will still use the legacy version to compile everything.
The order is as follows - glibc binutils gcc.
The reason to build glibc first? That’s because it affects to the content of binutils and gcc. :P
리눅스 툴체인의 완벽한 리빌드
우선 리눅스 헤더파일을 업데이트하고 툴체인 구성요소를 새로 컴파일한다. 순서는 linux-header glibc binutils gcc 순.
이렇게 하면 일단 업데이트는 끝나지만 툴체인 구성요소들의 기계어 코드는 아직 기존 툴체인이 생성한 코드에 기반하고 있다. 따라서 툴체인 구성요소 그 자체의 기계어 코드도 신버전의 코드로 갱신할 필요가 있다.
참고로, 젠투 리눅스의 경우 이 단계에서 gcc-config를 실행하여 새로 컴파일된 gcc가 선택되었는지의 여부를 확인하고 진행하여야 한다(그렇지 않으면 이전 gcc로 컴파일을 하므로 모든게 도루묵….. -o-).
이후 glibc binutils gcc의 순서로 다시 컴파일.
glibc부터 업데이트하는 이유라면….. binutils와 gcc의 내용에 영향을 주기 때문이려나. :P