构建U盘启动的嵌入式linux

前言:在参考了<<构建嵌入式linux系统>>一书和独孤九贱的<<怎样一步一步制作嵌入式Linux系统>>后,他们都是用CF卡来制作,对于大多数人估计和我一样,手上并没有板子和CF卡,而只有x86的电脑和USB盘,这里详细的描述一下我是如何制作的U盘启动,过程虽然破费很多时间,还是可以享受一下成功的喜悦,重要的是我们学习如何的编译kernel,如何建立自己的根文件系统,以及内核的引导启动过程,虽然这个还有许多不完善的地方,我们在学习中逐步完善,为了使初学者能更好全步完成usb启动自己的内核,我把过程全步详细的贴在这儿,很感谢有这些前辈的文档的帮助使我也能够进入自己的linux,接下让我们一起来分享吧:先介绍我编译的环境:Vmware6.0+rehat9.0(2.4.20)gcc3.2.2Vmware下编译内核有一些特殊之处,以及gcc的版本对编译也会有影响,下面我要讲到:第一步:制作交叉编译环境首先,我们要搞明白两个概念:一般我们工作的机器,称为开发机、主机;我们制作好的系统将要放到某台机器,如手机或另一台PC机,这台机我们称为目标主机。    我们一般开发机上已经有一套开发工具,我们称之为原生开发套件,我们一般就是用它们来写程序,那么,那什么又是交叉编译环境呢?其实一点也不神秘,也就是在开发机上再安装一套开发工具,这套开发工具编译出来的程序,如内核、系统工作或者我们自己的程序,是放在目标主机上运行的。  那么或许有初学者会问,直接用原生开发工具为目标主机编译程序不就完了?至少我当初是这么想的。一般来说,我们的开发机都是X86平台,原生开发套件开发的工具,也针对X86平台,而我们的目标主机可能是PowerPC、IXP、MIPS……所以,我们的交叉编译环境是针对某一类具体平台的。   一般来讲,交叉开发环境需要二进制工具程序、编译器、C链接库,嵌入式开发常用的这三类软件是:  Binutils  Gcc  uClibc当然,GNU包含的工具套件不仅于此,你还要以根据实际需要,进行选择我们这里用的386的系统,所以建立的文件只接用i386-linux-即可,如果是arm,就用arm-linux-大家一目了然,其它的类推。建立起交叉环境来之后,你就可以继续进行第二步,编译内核:

第二步、编译内核开发工具是针对某一类硬件平台,内核同样也是。这一步,我们需要用第一步中建立的工具,对内核进行编译,对于有内核编译经验的人来说,这是非常简单的;这里主要是要注意到一是在vmware编译环境,而是要用到U盘启动:第三步、建立根文件系统这个根文件系统,如果你的U盘足够大,可以直接cp主机上的,因为都386系统列,不过为了学习嵌入式系统,建议还是用“瑞士军刀”busybox吧。所谓的根文件系统,也就是建立我们平常看到的bin、dev、proc……这一大堆目录,以及一些必备的文件;这是我建好后的根文件系统架构:drwxrwxr-x2afaafa4096May1417:13bindrwxrwxr-x2afaafa4096May1416:44devdrwxrwxr-x3afaafa4096May1406:21etcdrwxrwxr-x2afaafa4096May1416:12liblrwxrwxrwx1rootroot11May1417:13linuxrc->bin/busyboxdr-xr-xr-x2afaafa4096May1416:04procdrwxrwxr-x2afaafa4096May1417:13sbindrwxrwxrwt2afaafa4096May1416:04tmpdrwxrwxr-x4afaafa4096May1417:13usrdrwxrwxr-x2afaafa4096May1416:04var另外,我们还需要为我们的目标系统安装一些常用的工具软件,如ls、ifconfig……当然,一个办法是找到这些工具的源代码,用第一步建立的交叉编译工具来编译,但是这些软件一是数量多,二是某些体积较大,不适合嵌入式系统,这一步,我们一般都是用busybox来完成的,包括系统引导软件init;最后,我们为系统还需要建立初始化的引导文件,如inittab……第四步、启动系统 在这一步,我们把建立好的目标、文件、程序、内核及模块全部拷贝到目标机存储器上,如硬盘。然后为系统安装bootloader,对于嵌入式系统,有许多引导程序可供我们使用。例如syslinux,lilo,grub,uboot等。关于bootloader的介绍,这里有两篇文章可以供大家学习参考:分别来自大陆和台湾的两们朋友的精彩分析:嵌入式系统BootLoader技术内幕詹荣开([email]zhanrk@sohu.com[/email]),Linux爱好者Jserv’sblog:探索Linuxbootloader的佳作 不过它们许多都有硬件平台的限制。当然,如果你是工作在X86,可以直接用grub来引导,这里采用的grub的引导,试过lilo的引导,不是很成功,需要lilo22.3以后的版本,下载试过也没有搞成功,留待以后研究,本文主要是用grub,相信很多和我一样的朋友希望学习用它来引导自己的U盘。做到这一步,将目标存储设备挂上目标机,如果顺利,就可以启动系统了。当然,针对某些特别的平台,不能像硬盘这样拷贝了,需要读卡器、烧录……但是基本的方法是相通的!第五步、优化和定制自己的个性化系统  通过前四步,我们已经得到了一个可以正常工作的系统。在这一步里,就是发挥你想像的时候了……子目录及说明目录内容boot目标板的引导加载程序,这里我放的是我的boot目录以及其中的内容build-tools建立交叉编译平台的工具源码debug调试工具及所有相关包doc 项目中用到的所有文档images编译好的内核映像,以及根文件系统kernel各个版本的Linux内核源码rootfs制作好的根文件系统sysapps目标板将要用到的系统应用系统,比如busybox,thttpd,udhcpd等tmp存放临时文件tools编译好的跨平台开发工具链以及C链接库我的启动脚本文件:myembed.sh#!/bin/bashexportPROJECT=embededexportPRJROOT=/home/afa/${PROJECT}exportTARGET=i386-1inuxexportPREFIX=${PRJROOT}/toolsexportTARGET_PREFIX=${PREFIX}/${TARGET}exportPATH=${PREFIX}/bin:/bin:/sbin:/usr/bin:/usr/sbincd${PRJROOT}大家在redhat可以用#>../myembed.sh 就可以执行了,这个好象困惑我一下,记住在./myembed.sh前要加一个点好了回到正题建立我们的嵌入式开发环境:

第二章建立交叉编译环境我没有采用手工建立的方式,而采用buildroot工具建立,当然如果开发你的商业硬件平台,厂家都会为你提供一个开发包,这里不去讨论。建立交叉开发工具链  准备工具:    buildroot-0.9.27.tar.tar只需要一个软件?对,其它的不用准备了,buildroot事实上是一个脚本与补丁的集合,其它需要用到的软件,如gcc、uClibc,你只需在buildroot中指明相应的版本,它会自动去给你下载。  事实上,buildroot到网上去下载所需的所有工作是需要时间的,除非你的带宽足够,否则下载软件时间或许会占去80%,而我在做这项工作之间,所需的工作链全部都在我本地硬盘上,我解压开buildroot后,新建dl文件夹,将所有工具源码的压缩包拷贝进去,呵呵,buildroot就不用去网上下载了。  我的软件清单:  Linux-libc-headers-2.4.27.tar.bz2  Gcc-3.3.4.tar.bz2  binutils2.15.91.0.2.tar.bz2  uClibc0.9.27.tar.bz2  genext2fs_1.3.orig.tar.gz  ccache-2.3.tar.gz以下是详细的步骤:[root@localhostafa]#../myembed.sh[root@localhostembeded]#cdbuild-tools/[root@localhostbuild-tools]#tarzxvfbuildroot-0.9.27.tar.gz[root@localhostbuild-tools]#cdbuildroot;mkdirdl[root@localhostbuildroot]#ls../dlbinutils-2.15.91.0.2.tar.bz2genext2fs_1.3.orig.tar.gzccache-2.3.tar.gzlinux-libc-headers-2.4.27.tar.bz2gcc-3.3.4.tar.bz2uClibc-0.9.27.tar.bz2[root@localhostbuildroot]#mv../dl/*dl/[root@localhostbuildroot]#makemenuconfig(如果用gcc4.0这里会有问题,自己修改一下即可,记得是有一句static语句,你可以去掉static就可以了)TargetArchitecture(i386)—>选择i386即可Buildoptions—>(${PRJROOT}/tools)Toolchainandheaderfilelocation?这个是问你编译好的东西存放在什么地方ToolchainOptions—>xlqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqkxxx—KernelHeaderOptionsxxxxKernelHeaders(Linux2.4.27kernelheaders)—>xx头文件它会自动去下载,不过应该保证与你将要用的内核是同一个版本xx—uClibcOptionsxxxx[]UsethedailysnapshotofuClibc?xx使用最近的uClibc的snapshotxx[]Enablelocale/gettext/i18nsupport?xxxx—BinutilsOptionsxxxxBinutilsVersion(binutils2.15.91.0.2)—>xxBinutils的版本xx—GccOptionsxxxxGCCcompilerVersion(gcc3.3.4)—>xxgcc的版本xx()Additionalgccoptionsxxxx[*]Build/installc++compilerandlibstdc++?xx支持的语言xx[]Build/installjavacompilerandlibgcj?(NEW)xxxx—CcacheOptionsxxxx[*]Enableccachesupport?(NEW)xx启用ccache的支持,它用于编译时头文件的缓存处理,用它来编译程序,第一次会有点慢,但是以后的速度可就很理想了,呵呵……xx—GdbOptionsxxxx[]BuildgdbdebuggerfortheTargetxxxx[]BuildgdbserverfortheTargetxxxx—CommonToolchainOptionsxxxmqqqqqqqqv(+)qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqjxtqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqPackageSelectionforthetarget—>这个什么都不用选,留待以后用busybox来搞定好了。TargetOptions—>[*]ext2rootfilesystemforthetargetdevice选择ext2作为根文件系统配置ok后:[root@localhostbuildroot]#make等一会儿………..会让你选择平台:Targetx86ProcessorFamily&216;1.Generic386(CONFIG_GENERIC_386)(NEW)&216;选这个好了输入1,等待………当出现下列:.comment–remove-div=.note–strip-unneeded2>/dev/null||true;/home/afa/embeded/build-tools/buildroot/build_i386/genext2fs-1.3/genext2fs-i503-b1068\-d/home/afa/embeded/build-tools/buildroot/build_i386/root-q-Dtarget/default/device_table.txt/home/afa/embeded/build-tools/buildroot/root_fs_i386.ext2[root@localhostbuildroot]#表示你编译成功:回头看一下自己的战利品:[root@localhostbuildroot]#cd../../tools/[root@localhosttools]#lsbinbin-ccachei386-linuxi386-linux-uclibcincludeinfolibmanusrbin:所有的编译工具,如gcc,都在这儿了,只是加了些指定的前缀;  bin-ccache:如果在Toolchainoptaion中没有选择对ccache的支持,就没有这一项了;i386-linux:链接文件;实际指向includei386-linux-uclibc:uclibc的相关工具;include:供交叉开发工具使用的头文件;info:gcc的info文件;lib:供交叉开发工具使用的链接库文件;第三章编译内核:这里基本上没有什么难的,记住两点好了,一是在vmware下编译,二是要支持usb启动:再者要以下原则为基础:1、功能上的选择,应该能够满足需要的情况下,尽量地小;  2、小不是最终目的,稳定才是;所以,最好编译内核前有一份目标机硬件平台清单以及所需功能清单,这样,才能更合理地裁减内核。准备工具Linux内核源码,我选用的是Linux-2.4.27.tar.bz2编译内核将Linux-2.4.27.tar.bz2拷贝至${PRJROOT}/kernel,解压#cdlinux-2.4.27配置#makeARCH=i386CROSS_COMPILE=i386-linux-menuconfig //建立源码的依存关系#makeARCH=i386CROSS_COMPILE=i386-linux-cleandep  //建立内核映像#makeARCH=i386CROSS_COMPILE=i386-linux-bzImageARCH指明了硬件平台,CROSS_COMPILE指明了这是交叉编译,且编译器的名称为i386-linux-XXX,这里没有为编译器指明路径,是因为我前面已将其加入至环境变量PATH。编译完成后我的内核是1MB,usb盘够装,不过这个可以再缩小一些,对我们的实验无关紧要继续下一步:安装内核    内核编译好后,将内核及配置文件拷贝至${PRJROOT}/images下。    #cparch/i386/boot/bzImage${PRJROOT}/images/bzImage-2.4.27-rmk5  #cpvmlinux${PRJROOT}/images/vmlinux-2.4.27-rmk5  #cpSystem.map${PRJROOT}/images/System.map-2.4.27-rmk5  #cp.config${PRJROOT}/images/2.4.27-rmk5.config这里呢,因为我时用不到modules所以下列步骤暂时不需要:—————————————//建立模块 #makeARCH=i386CROSS_COMPILE=i386-linux-modules //安装内核模块至${PRJROOT}/images #makeARCH=i386CROSS_COMPILE=i386-linux-  >INSTALL_MOD_PATH=${PRJROOT}/images/modules-2.4.18-rmk5  >modules_install——————————–附,内核选择:    内核编译记录:  —————————-注意,如果用vmware进行编译,那么需要注意一些地方:如果你在vmware下重新编译内核,硬盘用的是scsi的,以下选项必选:DeviceDrivers—>SCSIdevicesupport—><*>SCSIdisksupportDeviceDrivers—>SCSIdevicesupport—>SCSIlow-leveldrivers—><*>BusLogicSCSIsupport可以如果不选上这个当用grub启动时会出现:VFS:Cannotopenrootdevice"sda1"orunknown-block(0,0)Pleaseappendacorrect"root="bootoptionKernelpanic-notsyncing:VFS:Unabletomountrootfsonunknown-block(0,0)*关于USB,能选的都选上吧—————————————————————————–  Codematurityleveloptions不选    Loadablemodulesupport不选(这个以后再研究,进一步学习,毕竟这个还是要用的)    Processortypeandfeatures根据实际,选择处理器类型(我选默认的)    Generalsetup —>  [*]Networkingsupport[*]PCIsupport  (Any) PCIaccessmode[*]PCIdevicenamedatabase[*]SystemVIPC[*]Sysctlsupport  (ELF)Kernelcore(/proc/kcore)format[*]KernelsupportforELFbinaries[*]PowerManagementsupport   MemoryTechnologyDevices(MTD) —>MTD设备,我用USB盘,不选    Parallelportsupport —>不选    PlugandPlayconfiguration —>我的系统用不着即插即用,不选    Blockdevices —>  [*]Loopbackdevicesupport[*]RAMdisksupport  (4096) DefaultRAMdisksize(NEW)[*] InitialRAMdisk(initrd)support  上面三个一定要选上  Multi-devicesupport(RAIDandLVM) —> 不选  Networkingoptions —>基本上都选了  ATA/IDE/MFM/RLLsupport —> 用了默认的  TelephonySupport —>不选  SCSIsupport —>[*]SCSIdisksupport[*]Enableextrachecksinnewqueueingcode[*]ProbeallLUNsoneachSCSIdevice[*]VerboseSCSIerrorreporting(kernelsize+=12K)[*]SCSIlow-leveldrivers—>[*]SerialATA(SATA)support(这个应该串口硬盘的支持,选不选无所谓)[*]BusLogicSCSIsupport(这个一定要选)  FusionMPTdevicesupport —>不选  I2Odevicesupport —> 不选  Networkdevicesupport —> 根据实际情况选择(选默认)    AmateurRadiosupport —>不选    IrDA(infrared)support —>不选    ISDNsubsystem —>不选    OldCD-ROMdrivers(notSCSI,notIDE) —>不选    Inputcoresupport —>不选    Characterdevices —>  [*]Virtualterminal[*] Supportforconsoleonvirtualterminal[*]Standard/generic(8250/16550andcompatibleUARTs)serialsupport[*] Supportforconsoleonserialport    Multimediadevices —>不选    Filesystems —>  [*]Kernelautomounterversion4support(alsosupportsv3)  [*]Virtualmemoryfilesystemsupport(formershmfs)  [*]/procfilesystemsupport  [*]Secondextendedfssupport    Consoledrivers —>   &8226;VGAtextconsole 调试时接显示器用     Sound —>不选

  USBsupport —>[*]UHCIAlternateDriver(JE)support[*]USBMassStoragesupport  Kernelhacking —>不选Cryptographicoptions—>不选Libraryroutines—>不选第四章建立根文件系统构建工作空间时,rootfs文件夹用来存放根文件系统,  #cd${PRJROOT}/rootfs    根据根文件系统的基本结构,建立各个对应的目录:  #mkdirbindevetclibprocsbintmpusrvar  #chmod1777tmp  #mkdirusr/binusr/libusr/sbin  #ls  dev etc lib proc sbin tmp usr var  #mkdirvar/libvar/lockvar/logvar/runvar/tmp  #chmod1777var/tmp准备好根文件系统的骨架后,把前面建立的文件安装到对应的目录中去。  2、拷贝链接库    把uclibc的库文件拷贝到刚才建立的lib文件夹中:    #cd${PREFIX}/lib  [root@localhostlib]#cp*-*.so${PRJROOT}/rootfs/lib  [root@localhostlib]#cp-d*.so.[*0-9]${PRJROOT}/rootfs/lib3、拷贝内核映像和内核模块我们这里没有模块,暂时省下这一步[root@localhostboot]#cd${PRJROOT}/boot[root@localhostboot]#cp../images/bzImage-2.4.27-rmk5.[root@localhostboot]#mkdirgrub(建立grub目录,为grub启动文件做准备)[root@localhostboot]#cp/boot/grub/stage*grub/4、建立/dev下边的设备文件  在linux中,所有的的设备文件都存放在/dev中,使用mknod命令创建基本的设备文件。  mknod命令需要root权限用我这个脚本好了,比较简单:dev.sh重要的是要建上sda,sda1这两个,usb启动用的#!/bin/bashmknod-m600memc11mknod-m666nullc13mknod-m666zeroc15mknod-m644randomc18mknod-m600tty0c40mknod-m600tty1c41mknod-m600ttyS0c464mknod-m666ttyc50mknod-m600consolec51mknod-m660hdab30mknod-m660hda1b31mknod-m660hdbb30mknod-m660hdb1b31mknod-m660sdab30mknod-m660sda1b31mknod-m660sdbb30mknod-m660sdb1b31ln-s/proc/self/fdfdln-sfd/0stdinln-sfd/1stdoutln-sfd/2stderr5、添加基本的应用程序未来系统的应用程序,基本上可以分为三类:基本系统工具,如ls、ifconfig这些……一些服务程序,管理工具,如WEB、Telnet……自己开发的应用程序这里先添加基本的系统工具,有想过把这些工具的代码下载下来交叉编译,不过实在是麻烦,用BusyBox,又精简又好用……将busybox-1.00.tar.gz下载至sysapps目录下,解压:#tarzxvfbusybox-1.00.tar.gz  #cdbusybox-1.00    //进入配置菜单    #makeTARGET_ARCH=i386CROSS=i386-linux-PREFIX=${PRJROOT}/rootfsmenuconfig    //建立依存关系    #makeTARGET_ARCH=i386CROSS=i386-linux-PREFIX=${PRJROOT}/rootfsdep   //编译   #makeTARGET_ARCH=i386CROSS=i386-linux-PREFIX=${PRJROOT}/rootfs    //安装    #makeTARGET_ARCH=i386CROSS=i386-linux-PREFIX=${PRJROOT}/rootfsinstall配置busybox的说明:  A、如果编译时选择了:    RuntimeSUID/SGIDconfigurationvia/etc/busybox.conf系统每次运行命令时,都会出现“Usingfallbacksuidmethod”可以将它去掉,不过我还是在/etc为其建了一个文件busybox.conf搞定;   B、DoyouwanttobuildBusyBoxwithaCrossCompiler? 

    (i386-linux-gcc)CrossCompilerprefix    这个指明交叉编译器名称(其实在编译时的命令行已指定过了……)   C、安装选项下的(${PRJROOT}/rootfs)BusyBoxinstallationprefix,这个指明了编译好后的工具的安装目录。 D、静态编译好还是动态编译好?即是否选择  []BuildBusyBoxasastaticbinary(nosharedlibs)  动态编译的最大好处是节省了宝贵空间,一般来说都是用动态编译,不过我以前动态编译出过问题(其实是库的问题,不关busybox的事),出于惯性,我选择了静态编译,为此多付出了107KB的空间。  E、其它命令,根据需要,自行权衡。6、系统初始化文件  内核启动时,最后一个初始化动作就是启动init程序,当然,大多数发行套件的Linux都使用了与SystemVinit相仿的init,可以在网上下载SystemVinit套件,下载下来交叉编译。另外,我也找到一篇写得非常不错的讲解如何编写初始化文件的文件,bsd-init,回头附在后面。不过,对于嵌入式系统来讲,BusyBoxinit可能更为合适,在第6步中选择命令的时候,应该把init编译进去。[root@localhostetc]#viinittab::sysinit:/etc/init.d/rcS::respawn:/bin/sh[root@localhostetc]#mkdirinit.d[root@localhostetc]#viinit.d/rcS#!/bin/sh#SetPathPATH=/sbin:/binexportPATH#install/procmount-n-tprocnone/proc#reinstallrootfilesystembyread/writemode(need:/etc/fstab)mount-n-oremount,rw/#reinstall/procmount-n-oremount,rw-tprocnone/proc#setloipaddressifconfiglo127.0.0.1#sethostnamehostnameafaLinux[root@localhostetc]#chmodu+xinit.d/rcS(修改为可执行文件)[root@localhostetc]#vifstabproc/procprocdefaults00第五章建立自启动initrd.img文件九贱兄,以及《构建嵌入式linux系统》中都描述了用lilo来启动的过程,我没有成功,所以我选择用Grub。建立好自己的根文件系统之后,要用grub启动的话,需要建立自启动的initrd.img文件,以下是我制作自启的过程:这里有一篇这方面的介绍:有兴趣的可以看一下:Linux中的Ramdisk与Initrd(http://dev.csdn.net/article/82332.shtm)制作Ramdisk的镜像文件#ddif=/dev/zeroof=/dev/ram1dd:正在写入‘/dev/ram1’:设备上没有空间读入了8193+0个块输出了8192+0个块#mke2fs-m0/dev/ram1#mkdir/mnt/ram#mount/dev/ram1/mnt/ram将先前做好的rootfs根文件系统拷贝到ram1上.#>cp–rf*/mnt/ram#umount/dev/ram1#ddif=/dev/ram1of=${PRJROOT}/rootfs/initrd.img#fileinitrd.imginitrd.img:Linuxrev1.0ext2filesystemdata用loop设备来把他重新挂装到文件系统里:#mount-oloopinitrd.img/mnt/ram/查看/mnt/ram下的内容,和${PRJROOT}/rootfs/下的一模一样[root@localhostrootfs]]#ls/mnt/rambindevetcliblinuxrclost+foundprocsbintmpusrvar[root@localhostrootfs]]#umount/mnt/ram压缩initrd.img印象文件[root@localhostrootfs]#gzip-v9initrd.img initrd.img:90.8%–replacedwithinitrd.img.gz[root@localhostrootfs]#cpinitrd.img.gz../boot/(copy到boot目录中备用)第七章Grub来启动usb盘关于在vmware下如何mount上优盘以及如何格式化成ext2格式,和所遇到的问题的解决请看我的这篇blog:grub引导usb盘:这里不再详细描述:主要是建立grub.conf:[root@localhostrootfs]#cd../boot/grub/[root@localhostgrub]#vigrub.conf 1#grub.confgeneratedbyanaconda2#3#Notethatyoudonothavetorerungrubaftermakingchangestothisfile4#NOTICE:Youdonothavea/bootpartition.Thismeansthat5#allkernelandinitrdpathsarerelativeto/,eg.6#root(hd0,0)7#kernel/boot/vmlinuz-versionroroot=/dev/sda18#initrd/boot/initrd-version.img9#boot=/dev/sda10default=011timeout=1012titlemyusbRedHatLinux(2.4.27-8)13root(hd0,0)14kernel/boot/bzImage-2.4.27-rmk5roroot=/dev/sda1(这个一定是sda1,因为用U盘启动后,它认的是第一个SCSI盘,这里可以用df看一下,就是那个带/的盘)15initrd/boot/initrd.img.gz[root@localhostgrub]#ln-sgrub.confmenu.lst附:我的df命令显示[root@localhostgrub]#dfFilesystem1K-blocksUsedAvailableUse%Mountedon/dev/sda182542403085424474952440%/none12763201276320%/dev/shm/dev/sdb1631171638614793%/mnt/usb/home/afa/embeded/rootfs/initrd.img3963780318320%/mnt/ram建立usb目录:[root@localhostgrub]#mkdir/mnt/usb[root@localhostgrub]#mount/dev/sdb1/mnt/usbCp/boot文件到usb盘上:[root@localhostafa]#cd/mnt/usb[root@localhostusb]#mkdirboot[root@localhostusb]#cp-a${PRJROOT}/boot/*boot/[root@localhostroot]#umount/dev/sdb1[root@localhostroot]#grubgrub>root(hd1,0)Filesystemtypeisext2fs,partitiontype0x83grub>setup(hd1)grub>quit来看一下我的目录结构:[root@localhostembeded]#ls-Rlbootboot:total1532-rw-r–r–1rootroot1168816May1502:52bzImage-2.4.27-rmk5drwxr-xr-x2rootroot4096May1503:00grub-rw-r–r–1rootroot384523May1502:52initrd.img.gzboot/grub:total116-rw-r–r–1rootroot530May1503:00grub.conflrwxrwxrwx1rootroot9May1502:52menu.lst->grub.conf-rw-r–r–1rootroot512May1502:52stage1-rw-r–r–1rootroot106364May1502:52stage2附:用syslinux来启动优盘有的人可能比较喜欢这个,我来说一下如何用这个来启动,这个应该比grub还要简单一些,在redhat中已经带了syslinux包,如果没有你自己下载装一下好了.syslinux好处就是用windowsFAT来启动,这样我们可以在windows和linux都能看到其中的文件。你的盘可以用uboot格式化一下首先。试一下能否启动。#>我的syslinux.cfgTIMEOUT=5DEFAULTusb_bootLABELusb_bootkernelbzImageappendinitrd=init.img接下来制作MBR[root@afa-redroot]#umount/dev/sdb1(这一步一定要执行卸载它)[root@afa-redroot]#syslinux/dev/sdb1(生成LDLINUX.SYS文件)ok制作成功.比较简单,你可以按照syslinux的标准文档来写的更复杂一些,这不是我要说的,自己参考文档好了.http://gnawux.googlepages.com/syslinux这篇写的比较详细从这里我们看到不管你选什么bootloader,最重要的是要制作成自我解压的initrd.img文件,当然对于明白会做的人觉得这不难,但对于大多数初学者来说这个还是比较难的一次成功。希望有所帮助对爱好这个朋友。第八章启动usb盘这里就是修改BIOS设置成USB盘启动即可,无它,可能中间会报一下error,但无关紧要,最终进入到#>Shell界面.oK,大功告成.接下将要学习的如何整合新的应用程序如httpd,udhcp,….等。学习路的很长,不过总算有一个良好的开端了。最好的就是把这个过程写成一个Makefile文件一次搞定,这个梦想不错,看能否实现。参考资料:1.[原创]我也来学做嵌入式Linux系统V0.1(完整版)-ChinaUnix.net2.<<构建嵌入式linux系统>>

力微休负重,言轻莫劝人。

构建U盘启动的嵌入式linux

相关文章:

你感兴趣的文章:

标签云: