资源描述
ARM Linux启动过程分析(转载)
摘 要:嵌入式Linux的可移植性使得我们可以在各种电子产品上 看到它的身影。对于不同体系结构的处理器来说Linux的启动过程也 有所不同。本文以S3c2410 ARM处理器为例,详细分析了系统上电 后bootloader的执行流程及ARM Linux的启动过程。
关键词:ARM Linux bootloader启动过程Abstract:
We can see embedded Linux in kinds of electronic products because of its portability. Linux's start-up procedure for different processors is also different. This paper provides the analysis ofbootloader execution process and Linux kernel start-up procedure -taking the S3C2410 ARM processor as example.
Keywords: ARM Linux bootloader start-up procedure.引言
Linux最初是由瑞典赫尔辛基大学的学生Linus Torvalds在1991年开发出来的, 之后在GNU的支持下,Linux获得了巨大的开展。虽然Linux在桌面PC机上的 普及程度远不及微软的Windows操作系统,但它的开展速度之快、用户数量的日 益增多,也是微软所不能轻视的。而近些年来Linux在嵌入式领域的迅猛开展,更 是给Linux注入了新的活力。
一个嵌入式Linux系统从软件角度看可以分为四个局部[1]:引导加载程序 (bootloader), Linux内核,文件系统,应用程序。
其中bootloader是系统启动或复位以后执行的第一段代码,它主要用来初始化处理 器及外设,然后调用Linux内核。
Linux内核在完成系统的初始化之后需要挂载某个文件系统做为根文件系统(Root Filesystem)o根文件系统是Linux系统的核心组成局部,它可以做为Linux系统 中文件和数据的存储区域,通常它还包括系统配置文件和运行应用软件所需要的库。 应用程序可以说是嵌入式系统的“灵魂”,它所实现的功能通常就是设计该嵌入式系统 所要到达的目标。如果没有应用程序的支持,任何硬件上设计精良的嵌入式系统都 没有实用意义。
从以上分析我们可以看出bootloader和Linux内核在嵌入式系统中的关系和作 用。Bootloader在运行过程中虽然具有初始化系统和执行用户输入的命令等作用, 但它最根本的功能就是为了启动Linux内核。在嵌入式系统开发的过程中,很大一 局部精力都是花在bootloader和Linux内核的开发或移植上。如果能清楚的了解 bootloader执行流程和Linux的启动过程,将有助于明确开发过程中所需的工作, 从而加速嵌入式系统的开发过程。而这正是本文的所要研究的内容。
1 . Bootloader
1.1 Bootloader的概念和作用
Bootloader是嵌入式系统的引导加载程序,它是系统上电后运行的第一段程序,其[tekkamanninja@Tekkaman-Ninja var]$ cp
/usr/share/doc/HTML/homepage. css www/[tekkamann i nja@Tekkaman-Ni nja var!$ cp -r
/usr/share/doc/HTML/stylesheet-images www/直接在浏览器中输入开发板的IP地址(比方我的是 ://192.168.L2/),出 现fedora的欢迎网页。静态HTML调试成功。
CGI功能测试> 编写 HelloworldCGI.c 程序
[tekkamanninja@Tekkaman-Ninja source]$ vi helloworldCGI.c(主程序的程序开头一定要用Tab,而不是空格,不然编译可能不通过)
#include<stdio. h>#include<stdlib. h>
int main(void)(
printf (''Content-type: text/html\n\n,z);printf (z/<html>\n/z);
printf (,,<head><t i 11 e>CGIOutput</titleX/head>\nz/);
printf (z/<body>\n/z);printf (z/<hl>Hello, world.〈/hl〉\n〃);
printf (z/<body>\n/z);printf (,/</html>\n,/);
exit (0);.交叉编译生成CGI程序
[tekkamanninja@Tekkaman-Ninjasource!$ /home/tekkamanninja/working/gcc4. 1. l/gcc_4. 1. l-glibc-2. 3. 2
/arm-9tdmi-linux-gnu/bin/arm-9tdmi-linux-gnu-gcc -o helloworldCGI helloworldCGI.c将helloworldCGI拷贝至根文件系统的/var/www/cgi-bin/下
[tekkamanninja@Tekkaman-Ninja source!$ cp
helloworldCGI ・, /nfs/rootfs/var/www/cgi-bin/.测试
浏览器输入
://192.168.1.2/cgi-bin/helloworldCGI网页出现Hello, world.调试成功!
移植 Boa Web Server 至!J mini2440
2009-10-19 16:44:54|分类:原创-ARM9阅读723评论0 字号:大中小订阅今天终于完成了 Boa web server的移植工作,本次移植的主要参考资料都来自于互联网,由于这些 文章被转载得到处都是,我都不知道作者是谁。在这里衷心的感谢!!
一、Boa移植1、下载Boa源码
下载地址: :// boa.org/ 目前最新发行版本:0.94.13 (几年没更新版本了)下载boa-0.94.13.tar.gz (注意:假设从boa上下载的是boa-0.94.13.tar.tar,解压方式一样)
解压:tar xzf boa-0.94.13.tar.gz2、生成Makefile文件
进入 boa-0.94.13,直接运行 src/configure 文件cd src
./configure3、修改Makefile文件(注意:必须用cross-2.95.3)
CC = /usr/local/arm/2.95.3/bin/arm-linux-gccCPP = /usr/local/arm/2.95.3/bin/arm-linux-gcc -E
4、交叉编译make
5、去除调试信息,减小体积。(可选)arm-linux-strip boa
6、将编译好的程序放入根文件系统的/usr/sbin目录下。(网上说要放在bin下,但提示not found)cp boa /opt/studyarm/rootfs/usr/sbin/
二、配置BoaBoa需要在/etc目录下建立一个boa目录,里面放入Boa的主要配置文件boa.confo在Boa源码目 录下已有一个例如boa.conf,可以在其基础上进行修改。
cp /opt/studyarm/rootfs/etc/mkdir boa
chmod 777 boa/cd boa
cp /opt/studyarm/boa-0.94.13/boa.conf.
vi boa.conf1、Group的修改
修改Group nogroup为Group 0 (开发板上有的组,或者为0)修改User nobody (user组中有这个成员,不修改也可以)
根据你的开发板的情况设定。一定要存在的组和用户。
2、ScriptAlias 的修改修改 ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/ 为 ScriptAlias /cgi-bin/ /var/www/cgi-bin/
这是在设置CGI的目录,你也可以设置成别的目录。比方用户文件夹下的某个目录。
3、ServerName 的设置修改 #ServerName your.org.here ServerName your.org.here
注意:该项默认为未翻开,执行Boa会异常退出,提示“gethostbyname::No such file or directory”, 所以必须翻开。其它默认设置即可。你也可以设置为你自己想要的名字。比方我设置为:
huang-tomey.blog.163 此外,还需要将mime.types文件复制/etc目录下,通常可以从linux主机的/etc目录下直接复制即 可。
(以下配置和boa.conf的配置有关) 创立日志文件所在目录/va“log/boamkdir -m 777 /boa
创立HTML文档的主目录/var/wwwcd ..
mkdir -m 777 www创立CGI脚本所在录/var/www/cgi-bin
mkdir -m 777 www/cgi-bincd ..
cp /etc/mime.types etc/三、运行Boa
开发板操作:
[root@H3-studio]#./usr/sbin/boa如果发现boa没有运行,那么可以在开发板的/va“log/boa/error」og文件中找原因。
cat /var/log/boa/errorjog四、功能测试
静态网页测试将静态网页存入根文件系统的/var/www目录下(可以将主机/usr/share/doc/HTML/目录下的
index.html和img目录复制到/var/www目录下)
在根文件系统的/var目录下cp /usr/share/doc/HTML/index.html www/
cp -r /usr/share/doc/HTML/img www/直接在浏览器中输入开发板的IP地址(比方我的是 :〃 10.0.0.201),出现Redhat的网页。静
态HTML调试成功。
CGI功能测试、 编写 HelloworldCGLc 程序
cd /opt/studyarm/rootfs/var/www/cgi-bin/vi helloworldCGI.c
(主程序的程序开头一定要用Tab,而不是空格,不然编译可能不通过)#include<stdio.h>
#include<stdlib.h>int main(void)
printf("Content-type: text/html\n\nH);printf(n<html>\nM);
printf(n<head><title>CGI Output</titlex/head>\nn);printf(,,<body>\n");
printf("<h1 >Hello,world.</h1 >\n");printf(,,<body>\n");
printf("</html>\n");exit(O);
)
1 .交叉编译生成CGI程序linux-gnu-gcc -o helloworldCGI helloworldCGI.c
2 .测试浏览器输入 ://10.0.0.201/cgi-bin/helloworldCGI
网页出现Hello,world.调试成功!
USB摄像头的配置(ZC301)今天配置了 usb的摄像头,还算顺利,因为2.6.29.1已经支持好几种摄像头了,所以只需要对内核稍微进
行一下配置就好用了……摄像头是中星微的301 (zc301)
1配置内核(1)、
General setup -->Generic Driver Options —>
<*> Hotplug firmware loading support(2)、
Multimedia devices -->Video For Linux
Video capture adapters -->[*] V4L USB devices —>
<*>GSPCA based webcams —><*> ZC3XX USB Camera Driver
(3)、USB support -->
Support for Host-side USB—USB Host Controller Drivers
OHCI HCD support2、用命令测试
cat /dev/videoO > /a.jpg此命令用来抓取一副图像,可以用Ctrl+c来中断该命令
图像抓取后,在PC上可以采用gqview查看或者放到windows下看。
启动信息会增加以下几行:
usbcore: registered new interface driver usbfs usbcore: registered new interface driver hub usbcore: registered new device driver usbLinux video capture interface: v2.00
gspca: main v2.4.0 registered
usbcore: registered new interface driver zc3xx
zc3xx: registered
ohci_hcd: USB 1.1 'Open, Host Controller (OHCI) Driver s3c2410-ohci s3c2410-ohci: S3C24XX OHCIs3c2410-ohci s3c2410-ohci: new USB bus registered, assigned bus number 1
s3c2410-ohci s3c2410-ohci: irq 42, io mem 0x49000000
插入摄像头后
usb 1 -1: new full speed USB device using s3c2410-ohci and address 2
usb 1-1: configuration #1 chosen from 1 choice
gspca: probing 0ac8:301b
zc3xx: probe 2wr ov vga 0x0000
zc3xx: probe sensor -> 11
zc3xx: Find Sensor HV7131 R(c)
gspca: probe ok
完整的启动信息:
Copy linux kernel from 0x00050000 to 0x30008000, size = 0x00200000 ... done
zlmage magic = 0x016f2818
Setup linux parameters at 0x30000100linux command line is: Hconsole=ttySAC0 root=/dev/nfs nfsroot=10.0.0.200:/opt/studyarm/rootfs
ip=10.0.0.201:10.0.0.200:10.0.0.1:255.255.255.0:huang-tomey.blog.163 :eth0:off"
MACH TYPE = 782
NOW, Booting Linux
Uncompressing Linux
done, booting the kernel.
Linux version 2.6.29.1 (root@FriendlyARM) (gcc version 4.3.2 (Sourcery G++ Lite 2008q3-72)) #12 Wed
Oct 21 14:47:33 JST 2009
CPU: ARM920T [41129200] revision 0 (ARMv4T), cr=c0007177
CPU: VIVT data cache, VIVT instruction cache
Machine: Study-S3C2440
ATAG_INITRD is deprecated; please update your bootloader.
Memory policy: ECC disabled, Data cache writeback
CPU S3C2440A (id 0x32440001)
S3C24XX Clocks, (c) 2004 Simtec Electronics
S3C244X: core 405.000 MHz, memory 101.250 MHz, peripheral 50.625 MHz
CLOCK: Slow mode (1.500 MHz), fast, MPLL on, UPLL on
Built 1 zonelists in Zone order, mobility grouping on. Total pages: 16256
Kernel command line: console=ttySACO root=/dev/nfs nfsroot=10.0.0.200:/opt/studyarm/rootfs
ip=10.0.0.201:10.0.0.200:10.0.0.1:255.255.255.0:huang-tomey.blog.163 :ethO:off
irq: clearing subpending status 00000003
irq: clearing subpending status 00000002
PID hash table entries: 256 (order: 8, 1024 bytes)
Console: colour dummy device 80x30
console [ttySACO] enabled
Dentry cache hash table entries: 8192 (order: 3, 32768 bytes)
Inode-cache hash table entries: 4096 (order: 2, 16384 bytes)
Memory: 64MB = 64MB total
Memory: 60724KB available (3616K code, 354K data, 152K init)
Calibrating delay loop... 201.93 BogoMIPS (lpj=504832)
Mount-cache hash table entries: 512
CPU: Testing write buffer coherency: ok
net_namespace: 716 bytes
NET: Registered protocol family 16
S3C2440: Initialising architecture
S3C2440: IRQ Support
S3C24XX DMA Driver, (c) 2003-2004,2006 Simtec Electronics
DMA channel 0 at C4808000, irq 33
DMA channel 1 at C4808040, irq 34
DMA channel 2 at C4808080, irq 35
DMA channel 3 at c48080c0, irq 36
S3C244X: Clock Support, DVS off
bio: create slab <bio-0> at 0
SCSI subsystem initialized
usbcore: registered new interface driver usbfs
usbcore: registered new interface driver hub
usbcore: registered new device driver usb
NET: Registered protocol family 2
IP route cache hash table entries: 1024 (order: 0, 4096 bytes)
TCP established hash table entries: 2048 (order: 2, 16384 bytes)
TCP bind hash table entries: 2048 (order: 1,8192 bytes)
TCP: Hash tables configured (established 2048 bind 2048)
TCP reno registered
NET: Registered protocol family 1
NetWinder Floating Point Emulator V0.97 (extended precision)
Installing knfsd (copyright (C) 1996 okir@monad.swb.de).
JFFS2 version 2.2. (NAND) (SUMMARY) ©2001-2006 Red Hat, Inc.
yaffs Oct 1 2009 16:45:43 Installing,
msgmni has been set to 118
alg: No test for stdrng (krng)
io scheduler noop registered
io scheduler anticipatory registered (default)
io scheduler deadline registered
io scheduler cfq registered
Console: switching to colour frame buffer device 100x30
fbO: s3c241 Ofb frame buffer device
Serial: 8250/16550 driver, 4 ports, IRQ sharing enabled
s3c2440-uart.0: s3c2410_serial0 at MMIO0x50000000(irq =70)is aS3C2440
s3c2440-uart.1: s3c2410_serial1 at MMIO0x50004000(irq =73)is aS3C2440s3c2440-uart.2: s3c2410_serial2 at MMIO0x50008000(irq =76)is aS3C2440
brd: module loaded
loop: module loaded
dm9000 Ethernet Driver, V1.31
Now use the default MAC address :08:90:90:90:90:90
ethO (dm9000): not using net_device_ops yet
ethO: dm9000e at c486a000,c486e004 IRQ 51 MAC: 08:90:90:90:90:90 (chip)
Linux video capture interface: v2.00
gspca: main v2.4.0 registered
usbcore: registered new interface driver zc3xx
zc3xx: registered
Driver 'sd* needs updating - please use bus_type methods
S3C24XX NAND Driver, (c) 2004 Simtec Electronics
s3c2440-nand s3c2440-nand: Tacls=1,9ns Twrph0=4 39ns, Twrph1=1 9ns
NAND device: Manufacturer ID: Oxec, Chip ID: 0x76 (Samsung NAND 64MiB 3,3V 8-bit)
Scanning device for bad blocks
Bad craseblock 3339 at 0x00000342c000
Creating 8 MTD partitions on MNAND 64MiB 3,3V 8-bit":
0x000000000000-0x000000030000 : ,,bootloder"
0x000000050000-0x000000250000 : ,,kernelH
0x000000250000-0x000003ffc000 : "roof
0x000000800000-0x000000a00000 : "S3C2410 flash partition 3”
OxOOOOOOaOOOOO-OxOOOOOOeOOOOO : HS3C2410 flash partition 4"
0x000000e00000-0x000001800000 : HS3C2410 flash partition 5”
0x000001800000-0x000003000000 : nS3C2410 flash partition 6”
0x000003000000-0x000004000000 : HS3C2410 flash partition 7"
ohci_hcd: USB 1.1 'Open* Host Controller (OHCI) Driver
S3c2410-ohci s3c2410-ohci: S3C24XX OHCI
s3c2410-ohci s3c2410-ohci: new USB bus registered, assigned bus number 1
s3c2410-ohci s3c2410-ohci: irq 42, io mem 0x49000000
usb usb1: configuration #1 chosen from 1 choice
hub 1 -0:1.0: USB hub found
hub 1 -0:1.0: 2 ports detected
mice: PS/2 mouse device common for all mice
S3C24XX RTC, (c) 2004,2006 Simtec 曰ectronics
S3C2410 Watchdog Timer, (c) 2004 Simtec Electronics
s3c2410-wdt s3c2410-wdt: watchdog inactive, reset disabled, irq enabled
TCP cubic registered
NET: Registered protocol family 17
RPC: Registered udp transport module.
RPC: Registered tcp transport module,
drivers/rtc/hctosys.c: unable to open rtc device (rtcO)
usb 1-1: new full speed USB device using s3c2410-ohci and address 2
usb 1-1: configuration #1 chosen from 1 choice
gspca: probing 0ac8:301b
dm9000 dm9000.0: WARNING: no IRQ resource flags set.
ethO: link up, 100Mbps, full-duplex, Ipa 0x45E1
IP-Config: Complete:
device=ethO, addr=10.0.0.201, mask=255.255.255.0, gw=10.0.0.1,
host=huang-tomey, domain=, nis-domain=blog.163 ,
bootserver=10.0.0.200, rootserver=10.0.0.200, rootpath=
zc3xx: probe 2wr ov vga 0x0000
zc3xx: probe sensor -> 11
zc3xx: Find Sensor HV7131 R(c)
gspca: probe ok
Looking up port of RPC 100003/2 on 10.0.0.200
Looking up port of RPC 100005/1 on 10.0.0.200
VFS: Mounted root (nfs filesystem) on device 0:11.
Freeing init memory: 152K
mount all
★★★★★★★ytudy A RM******** ★★★★★★★★★★
Kernel version:linux-2.6.29.1
Student:Huang huahai
Data:2009.10.1
network interface
route: SIOCADDRT: File exists
IP :10.0.0.201
Netmask:255.255.255.0
Gateways 0.0.0.1
Please press Enter to activate this console.
[root@H3-Studio /]# usb 1-1: USB disconnect, address 2
gspca: disconnect complete
usb 1-1: new full speed USB device using s3c2410-ohci and address 3
usb 1-1: configuration #1 chosen from 1 choice
gspca: probing 0ac8:301b
zc3xx: probe 2wr ov vga 0x0000
zc3xx: probe sensor -> 11
zc3xx: Find Sensor HV7131 R(c)
gspca: probe ok
[root@H3-Studio /]#
ARM Linux多连接TCP服务器的应用程序设计嵌入式Linux工控主板EM9160的主要功能之一就是作为网络平台,工控领域中比拟常见的网络应用是利 用TCP/IP协议进行数据通讯。在网络应用中,通常都实现多连接的应用需求,本文主要介绍EM9160作 为TCP服务器方式的应用一一支持多连接的TCP服务器例如程序:Step3_TCPServero
TCP Socket 编程在进行网络应用程序开发方面大多是采用套接字Socket技术,嵌入式Unux的系统平台上也是如此。Socket 编程的基本函数有 socket(卜 bind( )> listen( )、accept( )、send( )> sendto(卜 recv( )> recvfrom( )> connect() 等。
支持多连接的TCP服务器应用例如
Step3_TCPServe是一个支持多个客户端的连接TCPServer例如,该例程采用了面向对象的C++ 编程,创立了 CTCPServer和CTCPCustom两个类,其中CTCPServer类负责侦听客户端的连接,一旦 有客户端请求连接,它就负责接受此连接,并创立一个新的CTCPCustom类对象与客户端进行通讯,然 后CTCPServer类接着监听客户端的连接请求,其流程如下:
作用类似于PC机上的BIOSo在完成对系统的初始化任务之后,它会将非易失性 存储器(通常是Flash或DOC等)中的Linux内核拷贝到RAM中去,然后跳 转到内核的第一条指令处继续执行,从而启动Linux内核。由此可见,bootloader 和Linux内核有着密不可分的联系,要想清楚的了解Linux内核的启动过程,我们 必须先得认识bootloader的执行过程,这样才能对嵌入式系统的整个启过程有清晰 的掌握。
2.2 Bootloader的执行过程
不同的处理器上电或复位后执行的第一条指令地址并不相同,对于ARM处理器来 说,该地址为0x00000000。对于一般的嵌入式系统,通常把Flash等非易失性存 储器映射到这个地址处,而bootloader就位于该存储器的最前端,所以系统上电或 复位后执行的第一段程序便是bootloadero而因为存储bootloader的存储器不同, bootloader的执行过程也并不相同,下面将具体分析。
嵌入式系统中广泛采用的非易失性存储器通常是Flash,而Flash又分为Nor Flash和Nand Flash两种。它们之间的不同在于:Nor Flash支持芯片内执行 (XIP, execute In Place),这样代码可以在Flash上直接执行而不必拷贝到RAM 中去执行。而Nand Flash并不支持XIP,所以要想执行Nand Flash上的代码,必 须先将其拷贝到RAM中去,然后跳到RAM中去执行。实际应用中的bootloader 根据所需功能的不同可以设计得很复杂,除完成基本的初始化系统和调用Linux内 核等基本任务外,还可以执行很多用户输入的命令,比方设置Linux启动参数,给 Flash分区等;也可以设计得很简单,只完成最基本的功能。但为了能到达启动Linux 内核的目的,所有的bootloader都必须具备以下功能[2]:
1)初始化RAM
因为Linux内核一般都会在RAM中运行,所以在调用Linux内核之前 bootloader必须设置和初始化RAM,为调用Linux内核做好准备。初始化RAM的 任务包括设置CPU的控制寄存器参数,以便能正常使用RAM以及检测RAM大 小等。
2)初始化串口
串口在Linux的启动过程中有着非常重要的作用,它是Linux内核和用户交互的方 式之一。Linux在启动过程中可以将信息通过串口输出,这样便可清楚的了解Linux 的启动过程。虽然它并不是bootloader必须要完成的工作,但是通过串口输出信息 是调试bootloader和Linux内核的强有力的工具,所以一般的bootloader都会在 执行过程中初始化一个串口做为调试端口。
3)检测处理器类型
Bootloader在调用Linux内核前必须检测系统的处理器类型,并将其保存到某个常 量中提供给Linux内核。Linux内核在启动过程中会根据该处理器类型调用相应的 初始化程序。
4)设置Linux启动参数
Bootloader在执行过程中必须设置和初始化Linux的内核启动参数。目前传递启动 参数主要采用两种方式:即通过struct param_struct和struct tag(标记列I表,tagged list)两种结构传递。structparam_struct是一种比拟老的参数传递方式,在2.4版 本以前的内核中使用较
多。从2.4版
展开阅读全文