當前位置:首頁 » 操作系統 » linux根文件系統製作

linux根文件系統製作

發布時間: 2024-04-19 11:16:12

『壹』 如何製作 linux 文件系統

一、什麼是文件系統 (Filesystem)
文件系統是包括在一個磁碟(包括光碟、軟盤、閃盤及其它存儲設備)或分區的目錄結構;一個可應用的磁碟設備可以包含一個或多個文件系統;如果您想進入一個文件系統,首先您要做的是掛載(mount)文件系統;為了掛載(mount)文件系統,您必須指定一個掛載點。

二、主要嵌入式採用的文件系統
Linux 中,rootfs 是必不可少的。PC 上主要實現有 ramdisk 和直接掛載 HD(Harddisk,硬碟) 上的根文件系統;嵌入式中一般不從 HD 啟動,而是從 Flash 啟動,最簡單的方法是將 rootfs load 到 RAM 的 RAMDisk,稍復雜的就是 直接從Flash 讀取的 Cramfs,更復雜的是在 Flash 上分區,並構建 JFFS2 等文件系統。
RAMDisk 將製作好的 rootfs 壓縮後寫入 Flash,啟動的時候由 Bootloader load 到RAM,解壓縮,然後掛載到 /.這種方法操作簡單,但是在 RAM 中的文件系統不是壓縮的,因此需要佔用許多嵌入式系統中稀有資源 RAM.

ramdisk 就是用內存空間來模擬出硬碟分區,ramdisk通常使用磁碟文件系統的壓縮存放在flash中,在系統初始化時,解壓縮到SDRAM並掛載根文件系統, 在linux系統中,ramdisk有二種,一種就是可以格式化並載入,在linux內核2.0/2.2就已經支持,其不足之處是大小固定;另一種是 2.4的內核才支持,通過,ramfs來實現,他不能被格式化,但用起來方便,其大小隨所需要的空間增加或減少,是目前linux常用的ramdisk技術。

initrd 是 RAMDisk 的格式,kernel 2.4 之前都是 image-initrd,Kernel 2.5 引入了 cpio-initrd,大大簡化了 Linux 的啟動過程,附合 Linux 的基本哲學:Keep it simple, stupid(KISS)。 不過cpio-initrd 作為新的格式,還沒有經過廣泛測試,嵌入式 Linux 中主要採用的還是 image-initrd.
Cramfs 是 Linus 寫的很簡單的文件系統,有很好的壓縮綠,也可以直接從 Flash 上運行,不須 load 到 RAM 中,因此節約了 RAM.但是 Cramfs 是只讀的,對於需要運行時修改的目錄(如: /etc, /var, /tmp)多有不便,因此,一般將這些目錄做成ramfs 等可寫的 fs.
SquashFS 是對 Cramfs 的增強。突破了 Cramfs 的一些限制,在 Flash 和 RAM 的使用量方面也具有優勢。不過,據開發者介紹,在性能上可能不如 Cramfs.這也是一種新方法,在嵌入式系統採用之前,需要經過更多的測試

三、建一個包含所有文件的目錄
1、建一個目錄rootfs 用來裝文件系統
2、mkdir bin dev etc lib proc sbin tmp usr var
3、ln -fs bin/busybox linuxrc(使用busybox)
4、到系統 /dev 把所有的device打一個包,拷貝到 dev下面(最省事的做法);或者使用mknod來自己建所需要的device,我自己用的如下:
crw-rw-rw- 1 root root 5, 1 2006-02-24 13:12 console crw-rw-rw- 1 root root 5, 64 2006-02-24 13:12 cua0 crw-rw-rw- 1 root root 63, 0 2006-02-24 13:12 dk0 crw-rw-rw- 1 root root 63, 1 2006-02-24 13:12 dk1 drwxr-xr-x 2 root root 4096 2006-02-24 13:12 flash brw-rw-rw- 1 root root 3, 0 2006-02-24 13:12 hda crw-rw-rw- 1 root root 36, 10 2006-02-24 13:12 ipsec crw-rw-rw- 1 root root 241, 0 2006-02-24 13:12 ixNpe crw-rw-rw- 1 root root 1, 2 2006-02-24 13:12 kmem crw-rw-rw- 1 root root 126, 0 2006-02-24 13:12 ledman lrwxrwxrwx 1 root root 16 2007-09-19 14:08 log -> /tmp/var/log/log crw-rw-rw- 1 root root 1, 1 2006-02-24 13:12 mem crw-rw-rw- 1 root root 90, 0 2006-02-24 13:12 mtd0 brw-rw-rw- 1 root root 31, 0 2006-02-24 13:12 mtdblock0 brw-rw-rw- 1 root root 31, 1 2006-02-24 13:12 mtdblock1 brw-rw-rw- 1 root root 31, 2 2006-02-24 13:12 mtdblock2 brw-rw-rw- 1 root root 31, 3 2006-02-24 13:12 mtdblock3 brw-rw-rw- 1 root root 31, 4 2006-02-24 13:12 mtdblock4 brw-rw-rw- 1 root root 31, 5 2006-02-24 13:12 mtdblock5 brw-rw-rw- 1 root root 31, 6 2006-02-24 13:12 mtdblock6 crw-rw-rw- 1 root root 90, 1 2006-02-24 13:12 mtdr0 crw-rw-rw- 1 root root 1, 3 2006-02-24 13:12 null crw-rw-rw- 1 root root 108, 0 2006-02-24 13:12 ppp crw-r——r—— 1 root root 5, 2 2006-03-29 15:56 ptmx drwxr-xr-x 2 root root 4096 2006-03-29 15:56 pts crw-rw-rw- 1 root root 2, 0 2006-02-24 13:12 ptyp0 brw-rw-rw- 1 root root 1, 0 2006-02-24 13:12 ram0 crw-rw-rw- 1 root root 1, 8 2006-02-24 13:12 random crw-rw-rw- 1 root root 5, 0 2006-02-24 13:12 tty crw-rw-rw- 1 root root 4, 0 2006-02-24 13:12 tty0 crw-rw-rw- 1 root root 3, 0 2006-02-24 13:12 ttyp0 crw-rw-rw- 1 root root 4, 64 2006-02-24 13:12 ttyS0 crw-rw-rw- 1 root root 1, 9 2006-02-24 13:12 urandom crw-rw-rw- 1 root root 1, 5 2006-02-24 13:12 zero舉例: mknod console c 5 1 這樣 crw-rw-rw- 1 root root 5, 1 2006-02-24 13:12 console
5、將編譯好的busybox拷貝到/bin下面,除了busybox外,所有其他的命令都是他的link
ash chgrp clear dd echo fgrep gzip ip ls modprobe mv ping pwd sed stty tar true zcat busybox chmod cp df egrep grep hostname kill mkdir more netstat ping2file rm sh sync tftp umount cat chown date dmesg false gunzip ifconfig ln mknod mount pidof ps rmdir sleep sysinfo touch uname
所有的命令你可以在busybox下面用make menuconfig來增減
6、同樣/sbin下面也是busybox的link
halt ifconfig init insmod klogd losetup lsmod mkswap modprobe reboot rmmod route swapoff swapon
[NextPage]
7、同樣/usr/bin下面也是busybox的link
basename dirname env free id logger reset tail tr tty uptime which xargs
awk cut expr head killall mkfifo sort test traceroute uniq wc whoami yes
上面幾乎是最全的link,各個看官可以酌情刪減,不過link也不佔什麼空間!
8、同樣/usr/sbin下面放著所有編譯完的可執行文件,具體就不多說了
9、非常重要之/lib,務必重視
找到你編譯環境的target目錄,把需要的lib文件先用strip壓縮(非target目錄下的,而已編譯環境提供的strip),先把最基本的libc, ld等等,必須同樣做跟target/lib裡面一樣的link.
然後根據特定的應用加相應的lib,不要把不用的加進去,lib比較占空間。

10、在/etc下面加上需要的配置文件,最最重要的是rcS
#!/bin/sh export PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/sbin/scripts UTC=yes mount -n -t proc proc /proc mount -n -t ramfs ramfs /tmp mount -n -t devpts devpts /dev/pts # build var directories /bin/mkdir -m 0777 /tmp/var /bin/mkdir -m 0777 /var/lock /bin/mkdir -m 0777 /var/log /bin/mkdir -m 0777 /var/run /bin/mkdir -m 0777 /var/tmp #/bin/mkdir -m 0777 /tmp/etc #/bin/cp -a /usr/etc//etc #/bin/cp -a /usr/dev//dev/ # loads the NPE ethernet moles into the kernel. insmod /lib/moles/2.6.13.2/intel/ixp400.ko # Firmware code for NPE Engine. cat /etc/IxNpeMicrocode.dat > /dev/ixNpe insmod /lib/moles/2.6.13.2/intel/ixp400_eth.ko netdev_max_backlog=500 insmod /lib/moles/led.ko insmod /lib/moles/push_button.ko下面的具體應用沒有再舉例加上了,這個是系統init必須的。
其他的情況類似如此了,下面裡面給了一個lunksys的GPL項目的target.

四、生成一個ramdisk
#!/bin/sh MODULE_NAME=ramdisk RAMPATH=`pwd` TMPPATH=${RAMPATH}/tmp SOURCE=${RAMPATH}/……/target if [ ! -d ${TMPPATH} ] then mkdir ${TMPPATH} fi if [ `whoami` != 'root' ] then { echo "You should run the shell as root, Please rerun as a root." echo "Aborting." exit 1 } fi # Clear in tmp path rm -rf ${TMPPATH}/tmpmnt rm -rf ${TMPPATH}/ramrootfs mkdir ${TMPPATH}/tmpmnt # Clear the old ramdisk rm -f ${RAMPATH}/$MODULE_NAME # Make a temp file which size is suitable dd if=/dev/zero of=${TMPPATH}/ramrootfs bs=1k count=6144 # Create a ext2 filesystem mke2fs -F -m 0 -i 2000 ${TMPPATH}/ramrootfs # Mount it to tmpmnt/ mount -o loop -t ext2 ${TMPPATH}/ramrootfs ${TMPPATH}/tmpmnt # Copy everything from kernel to this. cd ${TMPPATH}/tmpmnt echo ${SOURCE} cp -av ${SOURCE}/. cd ${TMPPATH} # Unmount it the ext2 filesystem umount ${TMPPATH}/tmpmnt cat ${TMPPATH}/ramrootfs | gzip -9 > /${RAMPATH}/ramdisk echo Copying ramdisk image to ${RAMPATH} sync這里給出一個自動生成腳本

五、生成一個cramfs
找到cramfs的toolchain./mkcramfs -r $(FS1_DIR) $(FS_NAME)。1
六、生成一個mksquashfs
找到squashfs的toolchain./mksquashfs $(FS_DIR) $(FS_NAME) -noappend -be -lzma -no-fragments -noI
做文件系統最困難和最可能出問題的地方是在/lib庫和/dev方面,請大家多注意這兩方面。

『貳』 Linux Encryption HOWTO 怎樣製作一個加密的文件系統

設定分區

您的硬碟(hda)最少應該包含三個分區:
hda1:這個小的沒加密的分區 應該 要求 一個 口令 為了 載入 加密 的根文件系統
hda2:這個分區應該包含你的加密根文件系統;確保它足夠大
hda3:這個分區就是你的當前的GNU/Linux系統

在這時,hda1和hda2沒有使用。hda3就是當前你安裝的linux發行版; /usr 和/boot不能另外分區裝載。

你的分區分布也許會像下面這樣:

# fdisk -l /dev/hda

Disk /dev/hda: 255 heads, 63 sectors, 2432 cylinders
Units = cylinders of 16065 * 512 bytes

Device Boot Start End Blocks Id System
/dev/hda1 1 1 8001 83 Linux
/dev/hda2 2 263 2104515 83 Linux
/dev/hda3 264 525 2104515 83 Linux
/dev/hda4 526 2047 12225465 83 Linux

安裝 Linux-2.4.27

有兩種主要的方案可用於在內核上添加 loopback加密支持:cryptoloop 和 loop-AES。本文是基於loop-AES方案的,因為因為它的特點是非常快 和非常優化實行 of Rijndael 用匯編語言。如果你有一個IA-32 (x86) CPU ,它將為您提供 最大的性能。另外,還有一些關於cryptoloop的安全關切.

首先,下載和解壓 loop-AES 軟體包:

wget http://loop-aes.sourceforge.net/loop-AES/loop-AES-v2.2b.tar.bz2
tar -xvjf loop-AES-v2.2b.tar.bz2

然後再下載內核源代碼和補丁並為內核源碼打上補丁:

wget http://ftp.kernel.org/pub/linux/kernel/v2.4/linux-2.4.27.tar.bz2
tar -xvjf linux-2.4.27.tar.bz2
cd linux-2.4.27
rm include/linux/loop.h drivers/block/loop.c
patch -Np1 -i ../loop-AES-v2.2b/kernel-2.4.27.diff

設置鍵盤映射:

mpkeys | loadkeys -m - > drivers/char/defkeymap.c

下一步,配置你的內核;確定下面的選項你已經選上了:

make menuconfig

Block devices --->

<*> Loopback device support
[*] AES encrypted loop device support (NEW)

<*> RAM disk support
(4096) Default RAM disk size (NEW)
[*] Initial RAM disk (initrd) support

File systems --->

<*> Ext3 journalling file system support
<*> Second extended fs support

(important note: do not enable /dev file system support)

編譯並安裝內核:
make dep bzImage
make moles moles_install
cp arch/i386/boot/bzImage /boot/vmlinuz

如果你的啟動器是grub,更新你的 /boot/grub/menu.lst或 /boot/grub/grub.conf文件:

cat > /boot/grub/menu.lst << EOF
default 0
timeout 10
color green/black light-green/black
title Linux
root (hd0,2)
kernel /boot/vmlinuz ro root=/dev/hda3
EOF

啟動器是lilo的話就更新/etc/lilo.conf並運行 lilo :
cat > /etc/lilo.conf << EOF
lba32
boot=/dev/hda
prompt
timeout=100
image=/boot/vmlinuz
label=Linux
read-only
root=/dev/hda3
EOF
lilo

現在重啟你的系統。

安裝Linux 2.6.8.1

像之前所說的那樣進行前面的部分,所用補丁是loop-aes'kernel-2.6.8.1.diff 。要注意的是你要安裝mole-init-tools軟體包以便你的系統支持模塊。
安裝util-linux-2.12b

這個losetup程序包含在util-linux-2.12b軟體包中。必須打補丁並重新編譯以使它支持加密。下載,解壓並打為util-linux打補丁:

wget http://ftp.kernel.org/pub/linux/utils/util-linux/util-linux-2.12b.tar.bz2
tar -xvjf util-linux-2.12b.tar.bz2
cd util-linux-2.12b
patch -Np1 -i ../loop-AES-v2.2b/util-linux-2.12c.diff
使用少於20個字元的密碼,鍵入:
CFLAGS="-O2 -DLOOP_PASSWORD_MIN_LENGTH=8"; export CFLAGS

安全可能是你主要關心的一個問題。為此,請不要使您的密碼少於20個字元。數據保密性不是免費的, 你必須以『支付』的形式使用長的密碼。

使用root用戶編譯安裝 losetup程序:
./configure && make lib mount
mv -f /sbin/losetup /sbin/losetup~
rm -f /usr/share/man/man8/losetup.8*
cd mount
gzip losetup.8
cp losetup /sbin
cp losetup.8.gz /usr/share/man/man8/

創建加密的根文件系統
用隨機數據填充目標分區:
shred -n 1 -v /dev/hda2
安裝加密loopback設備:
losetup -e aes256 -S xxxxxx /dev/loop0 /dev/hda2
為防止比較快的字典攻擊,推薦加上-S xxxxxx 選項,"xxxxxx" 是你隨機選取的種子(例如,你可能選擇 "gPk4lA" )。 同樣,為了防止啟動時的鍵盤映射問題,在密碼中不要使用非ASCII字元(方言,等)。Diceware站點提供了一種簡單的的方法去創建強大並容易記住的密碼。
現在開始創建ext3文件系統:
mke2fs -j /dev/loop0
檢測你輸入的密碼是正確的:
losetup -d /dev/loop0
losetup -e aes256 -S xxxxxx /dev/loop0 /dev/hda2
mkdir /mnt/efs
mount /dev/loop0 /mnt/efs
你可以比較已加密的和未加密的數據:

xxd /dev/hda2 | less
xxd /dev/loop0 | less

現在是時候安裝你的加密的linux系統了。如果你使用的是GNU/Linux發行版(譬如Debian, Slackware, Gentoo, Mandrake, RedHat/Fedora, SuSE, etc.), 運行下面的命令:

cp -avx / /mnt/efs
如果你使用是Linux From Scratch手冊,照著lfs手冊上所說的那樣進行配置,但要做以下修改:
Chapter 6 - Installing util-linux:

在解壓源代碼後打上 loop-AES 的補丁。
Chapter 8 - Making the LFS system bootable:
指向我們的下一章(創建啟動設備)。
--------------------------------------------------------

創建啟動設備
創建ramdisk
在開始時,先用chroot命令進入你的加密分區並創建啟動設備的掛載點:
chroot /mnt/efs
mkdir /loader
然後創建 initial ramdisk (initrd),它將會在以後用到:
cd
dd if=/dev/zero of=initrd bs=1k count=4096
mke2fs -F initrd
mkdir ramdisk
mount -o loop initrd ramdisk
如果您使用 grsecurity . 您可能會收到"Permission denied"的提示錯誤的信息;如果是這樣你將必須在chroot命令之前運行 mount命令。
創建文件系統的目錄組織並復制所需要的的文件進去:
mkdir ramdisk/{bin,dev,lib,mnt,sbin}
cp /bin/{bash,mount} ramdisk/bin/
ln -s bash ramdisk/bin/sh
mknod -m 600 ramdisk/dev/console c 5 1
mknod -m 600 ramdisk/dev/hda2 b 3 2
mknod -m 600 ramdisk/dev/loop0 b 7 0
cp /lib/{ld-linux.so.2,libc.so.6,libdl.so.2} ramdisk/lib/
cp /lib/{libncurses.so.5,libtermcap.so.2} ramdisk/lib/
cp /sbin/{losetup,pivot_root} ramdisk/sbin/
如果你看到像"/lib/libncurses.so.5: No such file or directory","/lib/libtermcap.so.2: No such file or directory"的信息,這是正常的。bash 只要求用這兩個庫中的其中一個。 你可以檢測哪一個才是你實際所需要的:
ldd /bin/bash
編譯sleep程序,它將防止密碼提示被內核信息所淹沒(例如當usb設備注冊時)。
cat > sleep.c << "EOF"
#include <unistd.h>
#include <stdlib.h>

int main( int argc, char *argv[] )
{
if( argc == 2 )
sleep( atoi( argv[1] ) );

return( 0 );
}
EOF

gcc -s sleep.c -o ramdisk/bin/sleep
rm sleep.c
創建初始化腳本(不要忘記替換掉你之前報選的種子 "xxxxxx" ):

cat > ramdisk/sbin/init << "EOF"
#!/bin/sh

/bin/sleep 3
/sbin/losetup -e aes256 -S xxxxxx /dev/loop0 /dev/hda2
/bin/mount -r -n -t ext3 /dev/loop0 /mnt

while [ $? -ne 0 ]
do
/sbin/losetup -d /dev/loop0
/sbin/losetup -e aes256 -S xxxxxx /dev/loop0 /dev/hda2
/bin/mount -r -n -t ext3 /dev/loop0 /mnt
done

cd /mnt
/sbin/pivot_root . loader
exec /usr/sbin/chroot . /sbin/init
EOF

chmod 755 ramdisk/sbin/init

卸載 loopback 設備並壓縮initrd:
umount -d ramdisk
rmdir ramdisk
gzip initrd
mv initrd.gz /boot/
從CD-ROM啟動
我強烈建議您從只讀的媒體里啟動您的系統,例如可啟動的光碟。
下載並解壓syslinux:
wget http://ftp.kernel.org/pub/linux/utils/boot/syslinux/syslinux-2.10.tar.bz2
tar -xvjf syslinux-2.10.tar.bz2
配置isolinux:
mkdir bootcd
cp /boot/{vmlinuz,initrd.gz} syslinux-2.10/isolinux.bin bootcd
echo "DEFAULT /vmlinuz initrd=initrd.gz ro root=/dev/ram0" \
> bootcd/isolinux.cfg

把iso映像刻錄到可啟動光碟中:

mkisofs -o bootcd.iso -b isolinux.bin -c boot.cat \
-no-emul-boot -boot-load-size 4 -boot-info-table \
-J -hide-rr-moved -R bootcd/

cdrecord -dev 0,0,0 -speed 4 -v bootcd.iso

rm -rf bootcd{,.iso}

從硬碟啟動

當你丟失了你的可啟動光碟時,啟動分區就可以派上用場了。請記住hda1是個可寫分區,因而並不是很可靠的,只有當你遇到緊急的情況時才使用它!

創建並掛載ext2文件系統:

dd if=/dev/zero of=/dev/hda1 bs=8192
mke2fs /dev/hda1
mount /dev/hda1 /loader

復制內核和initial ramdisk:

cp /boot/{vmlinuz,initrd.gz} /loader

如果你使用的是grub :

mkdir /loader/boot
cp -av /boot/grub /loader/boot/
cat > /loader/boot/grub/menu.lst << EOF
default 0
timeout 10
color green/black light-green/black
title Linux
root (hd0,0)
kernel /vmlinuz ro root=/dev/ram0
initrd /initrd.gz
EOF
grub-install --root-directory=/loader /dev/hda
umount /loader

如果你使用lilo:

mkdir /loader/{boot,dev,etc}
cp /boot/boot.b /loader/boot/
mknod -m 600 /loader/dev/hda b 3 0
mknod -m 600 /loader/dev/hda1 b 3 1
mknod -m 600 /loader/dev/ram0 b 1 0
cat > /loader/etc/lilo.conf << EOF
lba32
boot=/dev/hda
prompt
timeout=100
image=/vmlinuz
label=Linux
initrd=/initrd.gz
read-only
root=/dev/ram0
EOF
lilo -r /loader
umount /loader

最後一步 仍然保持chroot的狀態,修改/etc/fstab增加以下選項:
/dev/loop0 / ext3 defaults 0 1

去除 /etc/mtab 並從chroot中退出。最後 ,運行 "umount -d /mnt/efs"命令然後重啟系統。 如果有某些錯誤發生,你仍然可以在 LILO提示中用"Linux root=/dev/hda3"來啟動你未加密的分區。

如果一切都順利,你就可以重新分區你的硬碟和繼續加密你的hda3或hda4分區。在下面的腳本中,我們假設 hda3將掛載swap設備,hda4掛載/home目錄;你應該先初始化這兩個分區:
shred -n 1 -v /dev/hda3
shred -n 1 -v /dev/hda4
losetup -e aes256 -S xxxxxx /dev/loop1 /dev/hda3
losetup -e aes256 -S xxxxxx /dev/loop2 /dev/hda4
mkswap /dev/loop1
mke2fs -j /dev/loop2

然後在系統的啟動目錄里創建一個腳本並更新 /etc/fstab:
cat > /etc/init.d/loop << "EOF"
#!/bin/sh

if [ "`/usr/bin/md5sum /dev/hda1`" != \
" /dev/hda1" ]
then
echo -n "WARNING! hda1 integrity verification FAILED - press enter."
read
fi

echo "1st password chosen above" | \
/sbin/losetup -p 0 -e aes256 -S xxxxxx /dev/loop1 /dev/hda3

echo "2nd password chosen above" | \
/sbin/losetup -p 0 -e aes256 -S xxxxxx /dev/loop2 /dev/hda4

/sbin/swapon /dev/loop1

for i in `seq 0 63`
do
echo -n -e "\33[10;10]\33[11;10]" > /dev/tty$i
done

EOF

chmod 700 /etc/init.d/loop
ln -s ../init.d/loop /etc/rcS.d/S00loop
vi /etc/fstab
...
/dev/loop2 /home ext3 defaults 0 2

『叄』 嵌入式linux系統開發的具體步驟_嵌入式linux系統的搭建流程和要點

第一步、建立交叉編譯環境

沒有交叉開發經驗的讀者,可能一時很難接受這個概念。首先,要明白兩個概念:一般我們工作的機器,稱為開發機、主機;我們製作好的系統將要放到某台機器,如手機或另一台PC機,這台機我們稱為目標主機。

我們一般開發機上已經有一套開發工具,我們稱之為原生開發套件,我們一般就是用它們來寫程序,那麼,那什麼又是交叉編譯環境呢?其實一點也不神秘,也就是在開發岩困機上再安裝一套開發工具,這套開發工具編譯出來的程序,如內核、系統工作或者我們自己的程序,是放在目標主機上運行的。

那麼或許有初學者會問,直接用原生開發工具為目標主機編譯程序不就完了?至少我當初是這么想的。此棗絕一般來說,我們的開發機都是X86平台,原生開發套件開發的工具,也針對X86平台,而我們的目標主機可能是PowerPC、IXP、MIPS所以,我們的交叉編譯環境是針對某一類具體平台的。

一般來講,交叉開發環境需要二進制工具程序、編譯器、C鏈接庫,嵌入式開發常用的

這三類軟體是:BinutilsGuClibc

當然,GNU包含的工具套件不僅於此,你還要以根據實際需要,進行選擇

第二步、編譯內核

開發工具是針對某一類硬體平台,內核同樣也是。這一步,我們需要用第一步中建立的工具,對內核進行編譯,對於有內核編譯經驗的人來說,這是非常簡單的;

第三步、建立根文件系統

也就是建立我們平常看到的bin、dev、proc這一大堆目錄,以及一些必備的文件;

另外,我們還需要為我們的目標系統安裝一些常用的工具軟體,如ls、ifconfig當然,一個辦法是找到這些工具的源代碼,用第一步建立的交叉編譯工具來編譯,但是這些軟體一是森姿數量多,二是某些體積較大,不適合嵌入式系統,這一步,我們一般都是用busybox來完成的,包括系統引導軟體init;

最後,我們為系統還需要建立初始化的引導文件,如inittab

『肆』 如何製作Linux根文件系統

根文件系統一直以來都是所有類Unix操作系統的一個重要組成部分,也可以認為是嵌入式Linux系統區別於其他一些傳統嵌入式操作系統的重要特徵,它給Linux帶來了許多強大和靈活的功能,同時也帶來了一些復雜性。我們需要清楚的了解根文件系統的基本結構,以及細心的選擇所需要的系統庫、內核模塊和應用程序等,並配置好各種初始化腳本文件,以及選擇合適的文件系統類型並把它放到實際的存儲設備的合適位置。
Linux的根文件系統以樹型結構組織,包含內核和系統管理所需要的各種文件和程序,一般說來根目錄」/」下的頂層目錄都有一些比較固定命名和用途。
下面列出了一個Linux根文件系統中的比較常見的目錄結構:
/bin 存放二進制可執行命令的目錄
該目錄下存放所有用戶都可以使用的、基本的命令,這些命令在掛接其它文件系統之前就可以使用,所以/bin目錄必須和根文件系統在同一個分區中。
/bin目錄下常用的命令有:cat,chgrp,chmod,cp,ls,sh,kill,mount,umount,mkdir,m knod,[,test等「[」命令其實就是test命令,我們在利用Busybox製作根文件系統時,在生成的bin目錄下,可以看到一些可執行的文件,也就是可用的一些命令。
/dev 存放設備文件的目錄
該目錄下存放的是設備文件,設備文件是Linux中特有的文件類型,在Linux系統下,以文件的方式訪問各種設備,即通過讀寫某個設備文件操作某個具體硬體。比如通過"dev/ttySAC0"文件可以操作串口0,通過"/dev/mtdblock1"可以訪問MTD設備的第2個分區。
/etc 存放系統管理和配置文件的目錄
該目錄下存放著各種配置文件,對於PC上的Linux系統,/etc目錄下的文件和目錄非常多,這些目錄文件是可選的,它們依賴於系統中所擁有的應用程序,依賴於這些程序是否需要配置文件。在嵌入式系統中,這些內容可以大為精減。
/home 用戶主目錄,比如用戶user的主目錄就是/home/user,可以用~user表示
用戶目錄,它是可選的,對於每個普通用戶,在/home目錄下都有一個以用戶名命名的子目錄,裡面存放用戶相關的配置文件。
/lib 存放動態鏈接共享庫的目錄
該目錄下存放共享庫和可載入(驅動程序),共享庫用於啟動系統。運行根文件系統中的可執行程序,比如:/bin /sbin 目錄下的程序。
/sbin存放系統管理員使用的管理程序的目錄
該目錄下存放系統命令,即只有管理員能夠使用的命令,系統命令還可以存放在/usr/sbin,/usr/local/sbin目錄下,/sbin目錄中存放的是基 本的系統命令,它們用於啟動系統,修復系統等,與/bin目錄相似,在掛接其他文件系統之前就可以使用/sbin,所以/sbin目錄必須和根文件系統在同一個分區中。
/sbin目錄下常用的命令有:shutdown reboot fdisk fsck等,本地用戶自己安裝的系統命令放在/usr/local/sbin目錄下。

/tmp 公用的臨時文件存儲點
用於存放臨時文件,通常是空目錄,一些需要生成臨時文件的程序用到的/tmp目錄下,所以/tmp目錄必須存在並可以訪問。
/root 系統管理員的主目錄
根用戶的目錄,與此對應,普通用戶的目錄是/home下的某個子目錄。
/mnt 系統提供這個目錄是讓用戶臨時掛載其他的文件系統。
用於臨時掛載某個文件系統的掛接點,通常是空目錄,也可以在裡面創建一引起空的子目錄,比如/mnt/cdram /mnt/hda1 。用來臨時掛載光碟、硬碟。
/proc 虛擬文件系統,可直接訪問這個目錄來獲取系統信息。
這是一個空目錄,常作為proc文件系統的掛接點,proc文件系統是個虛擬的文件系統,它沒有實際的存儲設備,裡面的目錄,文件都是由內核臨時生成的,用來表示系統的運行狀態,也可以操作其中的文件控制系統。
/usr 最龐大的目錄,要用到的應用程序和文件幾乎都在這個目錄。
/usr目錄的內容可以存在另一個分區中,在系統啟動後再掛接到根文件系統中的/usr目錄下。裡面存放的是共享、只讀的程序和數據,這表明/usr目錄下的內容可以在多個主機間共享,這些主要也符合FHS標準的。/usr中的文件應該是只讀的,其他主機相關的,可變的文件應該保存在其他目錄下,比如/var。/usr目錄在嵌入式中可以精減。
/var 某些大文件的溢出區
與/usr目錄相反,/var目錄中存放可變的數據,比如spool目錄(mail,news),log文件,臨時文件。
---------------------------------------------------------------------
一、移植環境:
1、 Ubuntu 10.10發行版
2、 u-boot.bin
3、 目標機:FS_S5PC100平台
4、 交叉編譯器 arm-cortex_a8-linux-gnueabi-gcc
---------------------------------------------------------------------
二、移植步驟
1、 源碼下載
我們選擇的版本是busybox-1.17.3.tar.bz2下載路徑為:
http://busybox.net/downloads/
2、 解壓源碼
$ tar xvf busybox-1.17.3.tar.bz2
3、 進入源碼目錄
$ cd busybox-1.17.3
4、 配置源碼
$ make menuconfig

Busybox Settings --->
Build Options --->
[*] Build BusyBox as a static binary (no shared libs)
[ ] Force NOMMU build
[ ] Build with Large File Support (for accessing files > 2 GB)
(arm-cortex_a8-linux-gnueabi-) Cross Compiler prefix
() Additional CFLAGS

5、 編譯
$ make
6、 安裝
busybox默認安裝路徑為源碼目錄下的_install
$ make install
7、 進入安裝目錄下
$ cd _install
$ ls
bin linuxrc sbin usr
8、 創建其他需要的目錄
$ mkdir dev etc mnt proc var tmp sys root
9、 添加庫
在_install目錄下創建一個lib文件夾,將工具鏈中的庫拷貝到lib目錄下
$ mkdir lib
$ cp /home/linux/x-tools/arm-cortex_a8-linux-gnueabi/arm-cortex_a8-linux-gnueabi/lib/* ./lib/
刪除lib下的所有目錄、.o文件和.a文件,對庫進行瘦身以減小文件系統的大小
$ rm *.o *.a
$ arm-cortex_a8-linux-gnueabi-strip lib/*
10、 添加系統啟動文件
在etc下添加文件inittab
$ vim /etc/inittab
文件內容如下:

#this is run first except when booting in single-user mode.
:: sysinit:/etc/init.d/rcS
# /bin/sh invocations on selected ttys
# Start an "askfirst" shell on the console (whatever that may be)
::askfirst:-/bin/sh
# Stuff to do when restarting the init process
::restart:/sbin/init
# Stuff to do before rebooting
::ctrlaltdel:/sbin/reboot

在etc下添加文件fstab
$ vim /etc/fstab
文件內容如下:
#device mount-point type options mp fsck order
proc /proc proc defaults 0 0
tmpfs /tmp tmpfs defaults 0 0
sysfs /sys sysfs defaults 0 0
tmpfs /dev tmpfs defaults 0 0
這里我們掛在的文件系統有三個proc、sysfs和tmpfs,在內核中proc和sysfs默認都支持,而tmpfs是沒有支持的,我們需要添加tmpfs的支持
修改內核配置:
$ make menuconfigFile systems --->
Pseudo filesystems --->
[*] Virtual memory file system support (former shm fs)
[*] Tmpfs POSIX Access Control Lists
重新編譯內核
$ make zImage
在etc下創建init.d目錄,並在init.d下創建rcS文件
$ mkdir /etc/init.d -p
$ vim /etc/init.d/rcS
rcS文件內容為:
#!/bin/sh
# This is the first script called by init process
/bin/mount -a
為rcS添加可執行許可權:
$ chmod +x init.d/rcS
在etc下添加profile文件
$ vim /etc/profile
文件內容為:

#!/bin/sh
export HOSTNAME=farsight
export USER=root
export HOME=root
#export PS1="\[\u@\h \W\]\$ "
export PS1="[$USER@$HOSTNAME \W]\# "
PATH=/bin:/sbin:/usr/bin:/usr/sbin
LD_LIBRARY_PATH=/lib:/usr/lib:$LD_LIBRARY_PATH
export PATH LD_LIBRARY_PATH

11、 設備文件創建
根文件系統中有一個設備節點是必須的,在dev下創建console節點
$ mknod dev/console c 5 1
重要:新製作的文件系統尺寸若超出8M,刪除不需要的庫文件。

『伍』 如何利用busybox製作根文件系統

選定 busybox-1.9.2.tar.bz2 這個版本, 以靜態方式編譯, 即生成的 busybox 不需要共享庫的支持就能運行。這樣做我們就不需要布署程序庫了。缺點是自己寫的 arm-linux 程序在這個根文件系統中是不能運行的,因為缺少共享程序庫的支持。不過不用擔心,通過在目標機里以掛接 NFS 的方式, 將宿主機的 arm-linux-gcc 編譯器的庫文件掛到 arm-linux 的 /lib 下, 就可完美的運行我們自己的程序了。
現在開始製作靜態鏈接庫的根文件系統。

1、准備根文件系統
首先准備製作工具BusyBox1.9.2。
准備交叉編譯工具arm-linux-gcc 3.3.2。
在機器上建立rootfs的文件夾
#mkdir rootfs
在rootfs中建立linux系統中典型的文件夾
#cd rootfs
#mkdir root home bin sbin etc dev usr lib tmp mnt sys proc
#mkdir usr/lib usr/bin
#pwd
/home/su/rootfs
2、解壓源碼包
#tar xjf busybox-1.9.2.tar.bz2
#cd busybox-1.9.2
3、修改 Makefile,
#vi Makefile
將Makefile中的
CROSS_COMPILE ?=
改為
CROSS_COMPILE ?= /usr/local/arm/3.3.2/bin/arm-linux-
注:這個版本的 busybox 用 3.4.1 的 arm-linux-gcc 編譯有些問題, 用 3.3.2 版則可順利編譯。
4、定製 busybox
選擇busybox下全部的可執行程序
#make defconfig
進到配置選項
#make menuconfig
設置靜態編譯方式
Busybox Settings ---> Build Options ---> [*] Build BusyBox as a static binary (no shared libs)
Busybox Settings ---> Install Options ---> 中輸入建立根文件系統的文件所在的路徑/home/su/rootfs。
其它的默認。
確保 [*] Build BusyBox as a static binary (no shared libs) 被選中,保存退出
5、執行 make 編譯
#make
編譯出錯, 信息如下:
applets/applets.c:15:2: warning: #warning Static linking against glibc proces buggy executables
applets/applets.c:16:2: warning: #warning (glibc does not cope well with ld --gc-sections).
applets/applets.c:17:2: warning: #warning See sources.redhat.com/bugzilla/show_bug.cgi?id=3400
applets/applets.c:18:2: warning: #warning Note that glibc is unsuitable for static linking anyway.
applets/applets.c:19:2: warning: #warning If you still want to do it, remove -Wl,--gc-sections
applets/applets.c:20:2: warning: #warning from scripts/trylink and remove this warning.
applets/applets.c:21:2: error: #error Aborting compilation.
make[1]: *** [applets/applets.o] Error 1
按照提示,修改文件 applets/applets.c 第 21 行, 將
#error Aborting compilation.
注釋掉:
執行 make 重新編譯
#make
編譯通過, busybox 被生成了, 然後執行
#make install
busybox 就被安裝到指定的路徑下了/home/su/rootfs,這時可發現rootfs下多了個liunxrc的文件,bin、sbin下也多了很多文件。用ls –l命令查看其中的一個文件,可發現其是鏈接到busybox的一個連接符,所以我們之後在目標機上運行的命令大多都會調用busybox這個文件的。
若之前忘了指定路徑,默認生成到臨時目錄busybox-1.9.2/_install 下了。
6、編寫配置/etc下的初始化程序(可省略)
最簡單的做法是把busybox-1.9.2/examples/bootfloppy/etc下的全部文件拷到目標文件的etc目錄下
#cd /home/su/busybox-1.9.2/examples/bootfloppy/etc
#cp –rf * /home/su/rootfs/etc
也可自己寫這些文件。
7、把rootfs做成鏡像
#mkcramfs rootfs rootfs.cramfs
8、把rootfs.cramfs燒寫到目標機中。
9、運行目標機
這時會遇到一個錯誤信息:
Can』t open tty2
Can』t open tty3
Can』t open tty4
解決辦法:把/rootfs/etc/ inittab 文件的第三行「tty2::askfirst:-bin/sh」刪除掉。
返回到第7步重做。

現實中,動態編譯的方法更適合工程的需要,所以一般是採用動態的方法編譯根文件系統的。若選擇動態編譯的辦法,大體方法還是一樣的,存在一些不同之處是:
不同之處之一是:
進到配置選項
#make menuconfig
選擇動態方式
Busybox Settings ---> Build Options ---> [*] Build Shared libbusybox
不同之處之二是:
上面靜態編譯出現的出錯信息不會出現了,所以不需對程序做任何修改,但還是必須用arm-linux-gcc 3.3.2編譯,否則還是會有麻煩。
不同之處之三是(最大的不同之處):
編譯完成後,需進到rootfs目錄的lib中,往裡面添加一些庫文件
#cd /home/su/rootfs/lib
這里有點麻煩,我怎麼知道需要什麼庫文件的支持呢?
最簡單的辦法是把arm-linux-gcc 3.3.2下的整個lib庫拷進來,簡單省事。但是這么做存在一個問題,做出的根文件系統非常大。
另一個辦法是:
#cd /home/su/rootfs/bin
#arm-linux-readelf busybox | grep shared
這樣就可以顯示出系統運行起來需要什麼庫文件,再把相應的庫文件拷到/home/su/rootfs/lib下。一般而言,系統庫用到兩個:動態鏈接器ld-linux.so和c函數庫Glibc,Glibc包括:
ld-linux:動態鏈接庫,必需
libc: 標准c函數庫,必需
libm: 數學庫,一般需要
libdl: 用於動態裝載共享庫,較少用到
libcrypt: 加密附加庫,需要認證的程序用到,較少用
libpthread: POSIX線程庫,一般需要
如果需要某個函數庫,我們可以將這些庫和對應的符號鏈接拷到目標根文件系統的/lib目錄下。簡單起見,應該使用-d選項或-a選項調用cp命令,這樣可保留完整的符號鏈接信息。
例:
#cp –a libc.so.6 /home/su/rootfs/lib/
為了減少運行時庫的大小,我們應該使用交叉編譯版本即arm-linux-gcc 3.3.2的strip工具來處理根文件系統的庫文件,把二進制文件中的包含的符號表和調試信息刪除掉。
例:
#arm-linux-strip /home/su/rootfs/lib/*.so

注意:
使用busybox做文件系統時,運行make命令,系統會馬上顯示:
沒有/dev/null這個文件
但是還是能最終編譯出根文件系統,問題出在重啟linux系統,機器進不去了。提示出錯,信息如下:
/etc/rc.d/rc.sysinit: line 173:/dev/null: read-only file system
/etc/rc.d/rc.sysinit: line 173:/dev/null: read-only file system
/etc/rc.d/rc.sysinit: line 184:/dev/null: read-only file system
/etc/rc.d/rc.sysinit: line 184:/dev/null: read-only file system
/etc/rc.d/rc.sysinit: line 200:/dev/null: read-only file system
.
.
.
***An error occured ring the file system check.
***Dropping you to a shell;the system will reboot
***when you leave the shell
Give root password for maintenance
(or type Control-D to continue):
解決辦法:
按提示輸入root用戶的密碼,回車,可看到
(Repair filesystem)1#:
依次輸入命令:
(Repair filesystem)1# mount -n -o remount,rw /
(Repair filesystem)1# rm -f /dev/null
(Repair filesystem)1# mknod -m 0666 /dev/null c 1 3
(Repair filesystem)1# reboot
問題解決。

『陸』 有了linux內核和根文件系統如何來製作安裝盤

( 小於700兆)光碟上,是因為多個版本中有好多文件是相同的。這樣有一些光碟製作工具能夠能夠調整,多個原本一樣文件在光碟上實際是只存儲了一份。

如今的年頭都是DVD了,所以即使在多點版本也能作出來。
具體windows怎麼做的可以參考
(版權歸原作者啊...)

但linux來講,多個版本系統雖然都是linux 內核,但每個公司的都或多或少有自己的特點,裡面的二進制文件都有點差別,比如redhat 最早做的RPM包 ,opensuse也是RPM包加YAST管理器(openSUSE安裝過程就調用yast安裝的樣子)這兩家的軟體包都是RPM,但互相之間未必能完全兼容,因為軟體安裝時有一些系統路徑,軟體依賴桌面菜單配置等等之類的差別),debian的包是*.deb 的格式 採用DPKG管理,包的整體組織是pool的形式,還有別的linux版本,slackware 包的格式還不一樣,是tar.gz格式,所以基本上想像早期的多個文件存儲一份,控制整體體積存在一張光碟上的可能性好像就沒了。
但如果考慮,每個版本只選基本能安裝系統的CD(比如debian只要第一張cd盤就能安裝好系統)這樣每個版本選好盤,最終做在一張DVD上,應該是有可能性的。
那麼怎麼做呢?
很早以前(好像距今5年吧)我做過一張系統多引導盤,其實就是winpe dragonBSD grub引導盤 dos引導盤之類的放在一張光碟里(後來發現網上有個叫深山紅葉系統盤的,做出來就根那個差不多,只是我做的都是命令行的,沒有界面)
其實原理上是這樣的,系統光碟都有個引導區域,製作一個引導區具有這樣的功能
1.讀取別的光碟的引導區
講其他光碟(A)的引導區讀出來,作為一個文件,引到程序能載入這個文件,載入以後機器的內存 CPU寄存器之類的就根用A光碟啟動後一樣,就像你插入了debian盤,啟動了一樣。
2.將其他的引導盤直接讀入內存里,建立虛擬文件系統。
3.能夠當命令行工具,執行簡單其他程序。

關於1.有個補充點,既然這時候內存,cpu就像你用了debian盤啟動了一樣,那麼最終像製作的光碟裡面的目錄結構應當具有debian盤的結構。即假如原本有個文件 iso/a/b.deb 那麼最終的DVD也得有這個文件,不然安裝程序肯定找不到文件報錯。或者要修改debian盤的安裝程序一般是isolinux的樣子,使他知道最終的文件在哪裡。
很難三言兩語說清,我找到了很久前我參考的部分文章,你可以看看。

參考

(這個我以前沒看過)

PS:其實 /quote「關於1.有個補充點,既然這時候內存,cpu就像你用了debian盤啟動了一樣,那麼最終像製作的光碟裡面的目錄結構應當具有debian盤的結構。即假如原本有個文件 iso/a/b.deb 那麼最終的DVD也得有這個文件,不然安裝程序肯定找不到文件報錯。或者要修改debian盤的安裝程序一般是isolinux的樣子,使他知道最終的文件在哪裡。」/quote 是很難解決的,因為多個linux盤可能確實就有很多同一個位置同一個文件名字的,而且兩個還不一樣,這時只能調節linux盤的引導了,這要參考版本發行商的引導製作方法調整了。

熱點內容
功能點估演算法是 發布:2024-05-02 16:24:38 瀏覽:165
b站非法訪問 發布:2024-05-02 16:09:59 瀏覽:456
寶馬523壓縮機 發布:2024-05-02 16:00:40 瀏覽:611
冒險島m韓服安卓漢化包哪裡搞 發布:2024-05-02 16:00:24 瀏覽:955
雲伺服器託管平台 發布:2024-05-02 15:55:16 瀏覽:860
linux查看服務狀態 發布:2024-05-02 15:55:15 瀏覽:933
phpfirebird 發布:2024-05-02 15:45:55 瀏覽:125
思科伺服器怎麼修改imc地址 發布:2024-05-02 15:35:27 瀏覽:770
強制刪除文件夾的工具 發布:2024-05-02 15:34:34 瀏覽:770
sql存儲過程調用存儲過程 發布:2024-05-02 15:34:33 瀏覽:897