机顶盒
系统建立说明文档
日期
|
版本
|
人员
|
描述
|
2006-9-25
|
|
黄德智
|
初稿
|
2006-9-29
|
|
黄德智
|
补充了硬盘格式化和系统启动说明
|
PushTV以后可能有不同版本,而不同版本很可能对硬件平台有不同要求,为了以后查阅方便和给不熟悉系统的人员以可查看的文档,有必要对PushTV终端的系统及应用程序就特定硬件平台的安置情况和建立步骤,进行较全面的文档化。
文档描述范围
文档内容包括:硬件平台描述,Flash分区细节,系统及应用的安置,数据库的安置,硬盘使用规划及建立整个系统的操作和启动步骤。
硬件平台
目前版本的PushTV,终端硬件平台如下:
CPU
PowerPC 405,PPC架构,32 bit,252MHz,Big Endian (hton)。
存储设备
8M的norflash,512M电子硬盘或普通硬盘。
板卡
主板:DY-DVB-T V1.2
初期具备以太网卡。
Tuner
DVB—T或DVB—C。
Flash和硬盘
Flash和硬盘是PushTV机顶盒的两种信息存储介质。
Flash
Flash存放相对比较重要的信息。
分区信息
整个系统只有一块8M的norFlash,为了将系统的各个元素放置在Flash的不同区域,要对其进行分区。
分区细节表:
驱动
|
大小
|
起始地址
|
描述
|
Mtd0
|
0x1000 (4096)
|
0x00000000
|
Product global infomation
|
Mtd1
|
0x1000 (4096)
|
0x00001000
|
Loader and ca information
|
Mtd2
|
0x1000 (4096)
|
0x00002000
|
Loader and ca information(backup)
|
Mtd3
|
0x1000 (4096)
|
0x00003000
|
Bios data
|
Mtd4
|
0xb0000 (720896)
|
0x00004000
|
Linux kernel
|
Mtd5
|
0x100000 (1048576)
|
0x000b4000
|
Linux filesystem + loader
|
Mtd6
|
0x9000 (36864)
|
0x001b4000
|
Boot logo
|
Mtd7
|
0x40000 (262144)
|
0x001bd000
|
Database
|
Mtd8
|
0x5e3000 (6172672)
|
0x001fd000
|
Applications
|
Mtd9
|
0x20000 (131072)
|
0x007e0000
|
OpenBIOS
|
各分区的用途见“描述”。
Flash的驱动源代码文件为39服务器:/home/stb2k/product/kernel/linux-2.4.17_mvl21/drivers/mtd/maps/redwood.c。如果需要更改分区,修改该文件后重新编译内核即可。
代码文件中有两个重要的宏:CONFIG_MTD_MAPS_NORFLASH_M2000T和CONFIG_MTD_MAPS_NORFLASH_R2000C。这两个宏在编译linux kernel时指定,分别用于编译M2000T和R2000C系统的flash驱动。
数据检查
Flash的数据检查只对mtdblock7区的数据进行检查。检查工作在开机后进行,步骤如下:
把mtdblock7区挂载到文件系统上;
1、 如果挂载不成功或上面的文件不正常:
a) 从backup复制FLASH_DB和data目录到内存中;
b) 打包、重新烧写database(mtdblock7)区
2、 卸载database(mtdblock7)区;
这部分代码在文件/home/stb2k/develop.m2000/src/pushtvad_init/check_flash.cpp中实现,它和硬盘检查功能一起被编译为pushtvad_init.out(硬盘检查见“硬盘自动分区”部分),由autorun.sh负责启动。
硬盘
硬盘用来放置PushTV业务数据库、下载的素材和播放日志。采用512M电子硬盘或普通硬盘。
分区信息
电子硬盘空间总数为512M,分区细节:
驱动
|
大小
|
挂载节点
|
描述
|
Hda1
|
7 blocks(3528K)
|
/hd/hd0
|
存放PushTV业务数据库
|
Hda2
|
7 blocks(3528K)
|
/hd/hd1
|
存放PushTV业务数据库(backup)
|
Hda3
|
剩余的(约490M)
|
/hd/hd2,/hd/hd3
|
存放素材和播放日志
|
普通硬盘
驱动
|
大小
|
挂载节点
|
格式
|
描述
|
Hda1
|
64M
|
/hd/hd0
|
Ext2
|
存放PushTV业务数据库
|
Hda2
|
64M
|
/hd/hd1
|
Ext2
|
存放PushTV业务数据库(backup)
|
Hda3
|
256M
|
/hd/hd2
|
Ext2
|
存放播放日志
|
Hda4
|
剩余的
|
/hd/hd3
|
avf
|
存放素材
|
自动分区
有很多时候,硬盘可能不能正常工作了,或是上面的数据受到破坏,所以,在每次开机后,要对硬盘(无论是电子硬盘还是普通硬盘)进行检查,相关代码文件是/home/stb2k/develop.m2000/src/pushtvad_init/ check_hd.cpp。
硬盘检查流程如下:
1、 首先检查是否有硬盘,如果没有,则什么操作也不执行;
2、 如果有硬盘,则检查是什么硬盘(电子硬盘还是普通硬盘);
3、 根据不同的硬盘,查看其分区信息是否符合要求;
a) 如果不符合分区要求,则对硬盘重新分区,重新格式化;
4、 检查数据库文件是否被损坏
a) 如果从backup中复制HD_DB下的数据库文件到hda1;
5、 数据库备份操作
其中,判断有无硬盘和是什么硬盘,是通过检查机顶盒上/proc/ide/hda/identify的数值进行的。
下面说明关于硬盘分区和格式化操作的内容。
硬盘分区是通过命令sfdisk进行的,执行以下命令将完成对硬盘的重新分区:
sfdisk /dev/hda < XXX.save
其中/dev/had是硬盘驱动器的驱动,XXX.save是具体的分区信息配置文件,格式如下:
,7,83
,7,83
,,83
这是对电子硬盘进行分区时使用的配置文件。格式为:用“,”将三个整数分隔开来,第一个是某个区的开始位置,如果没有则为默认值,即前一个区的末尾;第二个数为该区的大小,单位为“柱面”,第三个为格式,83表示linux分区(
5
为Extended,7为HPFS/NTFS,
82为swap格式)。利用mke2fs来格式化分区了:
mke2fs /dev/hda1
mke2fs会用到一些库文件(ppc_405-ldd mke2fs):
libext2fs.so.2 => libext2fs.so.2 (0x0)
libcom_err.so.2 => libcom_err.so.2 (0x0)
libe2p.so.2 => libe2p.so.2 (0x0)
libuuid.so.1 => libuuid.so.1 (0x0)
libc.so.6 => libc.so.6 (0x0)
/lib/ld.so.1 => /lib/ld.so.1 (0x0)
建立整个系统
这一部分讲述如何在硬件平台建立PushTV终端的整个系统(关于bios程序的写入随后将做补充)。建立系统就是要将以下各个软件元素写到flash和硬盘的指定位置。包括:linux kernel;filesystem + loader;Database和Applications。每一项对应于flash的特定区域。
建立方式有两种:
1、 逐块烧写
就是这些软件元素将逐个的写到flash的对应区域上。一般按照以下顺序进行:linux kernel——>filesystem + loader——>Database——>Applications。第一个盒子只能通过这种方式建立系统。
2、 8M的flash整体烧写
如果已经有至少一个盒子上成功建立了系统,那可将这个(些)盒子中flash上的数据整体读取,继而写入其它将要建立系统的盒子的flash中。这样新建立系统的盒子中flash上的数据就与摸板盒子的完全一样,也达到了建立系统的目的。但有一点需要注意:因为这样多个盒子上的flash数据完全一致,从而造成以太网IP地址冲突。
这里主要描述第一种建立方式。
编译内核
内核采用MontaVista Linux 2.1,Kernel 2.4.17,编译目录位于39服务器:/home/stb2k/product/kernel/linux-2.4.17_mvl21/。
将根据一定编译选项编译好的系统内核写入flash的指定区域,是这一步的主要任务。首先我们需要为该硬件平台编译一个内核文件。
linux内核可通过两种方式启动:nfs网络启动;本地flash启动。我们分别编译这样的两个内核:
NFS 内核
用于nfs启动的内核:
(1)、make menuconfig
(2)、General setup
a、Default bootloader kernel arauments [*]
b、Initial kernel command string [console=ttyS0,115200 root=/dev/nfs]
(3)、Networking options
TCP/IP networding [*]
IP: kernel level autoconfiguration [*]
IP: BOOTP support [*]
(4)、File systems
Network File Systems
NFS file system support <*>
Root file system onNFS [*]
flash内核
为烧写到flash上编译的内核:
(1)、make menuconfig
(2)、General setup
a、Default bootloader kernel arauments [*]
b、Initial kernel command string [console=ttyS0,115200 root=/dev/mtdblock5]
(3)、Networking options
TCP/IP networding [*]
IP: kernel level autoconfiguration [ ]
(4)、File systems
Network File Systems
NFS file system support < >
退出时保存设置,执行命令:(make clean;) make dep; make zImage(回车)
编译好的内核文件被放置在:arch/ppc/boot/images/ 目录下,文件名为zImage.treeboot,大小在680k到700k之间。将编译好的NFS内核复制到目录/ tftpboot/目录下,编译好的烧写到flash上的内核复制到/opt/hardhat/devkit/ppc/405/target/root/目录下,如果是要通过windows的“超级终端”进行内核文件的烧写,则后一个复制操作没需要。这两个目录都是在另一个配置文件中指定,会在本文档的其它部分进行说明。
这两个内核用途不同,NFS 内核是为了从网络上启动机顶盒,而flash内核将被写到盒子的flash中的“Linux kernel”区,用来本地启动。
好,flash内核有了,把它烧进盒子吧。
烧写内核
烧写内核的任务就是将已经编译好的flash内核文件写到某个盒子的flash的“Linux kernel”分区。内核文件可通过两种方式写入flash:一种是通过串口进入bios进行烧写;另一种是网络启动后通过命令dd进行烧写。
通过bios进行烧写
将要烧写kernel的盒子已经有了bios程序,我们可以通过串口访问它。
用一根串口线将盒子和PC(windows os)的COM1相连,运行PC上的“超级终端”工具(开始-程序-附件-通讯),输入一个有意义的名称后进行如下配置:每秒位数:115200;数据位:8;奇偶效验:无;停止位:1;数据流控制:无。
加电启动机顶盒,这时可看到一些启动信息。
如果在启动时连续按下回车键(或干脆按住),即可进去盒子的bios程序。选择2(Change a Boot Device),这里可以设置盒子启动方式,选择3(Serial Port(串口启动)),回车退出;反复按6(Toggle Update Flash),使得当前状态为Update Flash: Enabled (on exit),再进行保存(按S),最后按0(Exit Menu and Boot Application),退出重新引导。选择“超级终端”上的菜单“发送”——>“发送文件”,在该对话框中选择文件为编译的flash内核(或许把那个内核文件通过FTP等工具复制到本机会更方便),协议选择Kermit,点击“发送”,几分钟后发送框消失,敲回车,对于“which may erase existing code and data, Do you wish to continue?”的询问,选择Y,看到“please reset the board to continue!”的信息后表示内核文件烧写完毕,可从本机启动了。
但这时bios的设置还是从串口启动,改回去:
1、 启动时进入bios;
2、 设置盒子启动方式为1,从flash启动;
3、 按S保存;
好,通过bios进行内核文件的烧写就操作完了。
网络启动后dd
网络启动后通过dd命令烧写内核是另一个途径,但要求在flash的驱动代码中,允许对flash进行写操作。
同样进入机顶盒的bios:
1、 选择3(Change IP Addresses),设置盒子的NFS网络地址,其中local=192.168.132.233,remote=192.168.132.39,为39服务器。记录下后面的hwaddr的值,下面要用;
2、 启动方式为2;
网络启动还涉及到一个配置文件,该文件名为bootptab,位于39服务器的/etc/目录下。编辑该文件中的这几项:硬件地址ha,使得它等与你上面的hwaddr;NFS内核文件bf,使得它等于你编译好的那个NFS 内核。注意每项后面都有“:”号。保存退出
回到“超级终端”窗口,按0进行引导启动。
启动结束后,要求登陆,输入root。
这时,在“超级终端”窗口中看到的文件和目录就是39服务器上/opt/hardhat/devkit/ppc/405/target/目录下的内容,该目录在文件bootptab中指定。如果你在“编译内核”中已经把编译好的flash内核复制到了root目录下,那这时就应该能看到。
我们要将该内核写入flash的linux kernel区域,该分区对应的驱动程序为mtd5,执行以下命令(比如内核文件为zImage.m2000t):dd if=zImage.m2000t of=/dev/mtdblock5。命令执行完毕也就是烧写动作完毕。
制作文件系统和应用
Flash上Linux filesystem + loader,Database和Applications分区分别放置文件系统、数据库和应用程序。这三部分也将以cramfs的文件格式写到flash上。
Linux filesystem + loader
该区放置文件系统,当盒子从flash上的内核启动时,默认装载这个分区的文件系统。
我们需要做的就是将一个固定层次结构的目录及它内部的的文件和子目录,通过mkcramfs命令打包成一个cramfs文件,然后复制(dd命令)该文件到flash的Linux filesystem + loader区。
需要打包的、固定层次结构的目录在39的/home/stb2k/product/pushtv_fsloader/目录下,这是一个典型的linux文件系统结构。mkcramfs位于/opt/hardhat/host/bin/下,参考与pushtv_fsloader同一目录下的pushtv_loader.mkfs脚本文件,这里完成了打包和复制cramfs文件到指定位置的操作。
这里有两个shell文件需要关注:etc/init.d/mountall.sh和etc/inittab。
mountall.sh:该脚本在系统装载进文件系统后自动执行,脚本完成以下几类操作:
1、 装载其它flash分区和硬盘(mount)
Flash中的Database和Applications两个分区并没有被kernel直接使用,它们需要挂载(mount)到文件系统中才能被使用。但这两个区操作不完全一样:Database区被挂载进来,读取到数据后马上就被卸载了,它两个目录的数据被复制到rd目录下;而Applications挂载后一直保持对它的访问,它被挂到/fd/fd1/目录下。
2、 在内存中构建rd目录
3、 装载驱动程序
有部分驱动程序在这个脚本中被装载,有lib/os_core.o;/lib/stbrtc.o;/lib/ircombo.o和/lib/frontend.o。
inittab:文件中有一句:-/bin/sh /app/bin/autostart.sh,这设置了系统启动后自动执行脚本/app/bin/autostart.sh,而在autostart.sh脚本中将启动PushTV终端应用程序。
Database
这个区放置DTV数据库(FLASH_DB)。将此数据库放置在flash上,是为了在没有硬盘的情况下,DTV还可以播放,而flash空间有限,设计PushTV业务的数据库将被放置在硬盘上。
但在实际中,该flash分区除了放置一部分数据库外还放有一个data的目录,包含IP地址的interfaces文件就在该目录下的etc目录下。
打包的目标目录位于39的/home/stb2k/product/pushtv_app/fd2目录。pushtv_fd2.mkfs脚本完成了打包和复制文件工作。
Applications
这个分区放置PushTV的终端应用程序以及用到的库文件及驱动文件等。
打包的目标目录位于39的/home/stb2k/product/pushtv_app/pb1100目录。pushtv_app.mkfs脚本完成了打包和复制文件工作。
以上三个目录生成的cramfs文件也需要复制到/opt/hardhat/devkit/ppc/405/target/root/目录下,这样,从网络启动后才能进行访问,继而通过dd命令写入对应区域。需要注意的是,各个分区的大小是固定的,生成的文件如果超过分区大小,就需要进行裁减了。
烧写文件系统和应用
烧写文件系统和应用同通过nfs启动后烧写内核文件步骤相同。只是它们写的目标位置不同:
1、 烧写文件系统:
dd if=zImage.m2000t of=/dev/mtdblock5
2、 烧写Database
dd if=zImage.m2000t of=/dev/mtdblock7
3、 烧写Applications
dd if=zImage.m2000t of=/dev/mtdblock8
同步数据库
整个PushTV数据库被分为DTV数据库和PushTV业务相关数据库两部分,其中PushTV业务相关数据库放置在硬盘上,系统启动后被mount(在autorun.sh中进行)到/dev/hda1后直接进行查询和修改。而DTV数据库放置在flash上(Database区),系统启动时mount(在mountall.sh中进行)到/mnt/目录,读取其中的数据到内存后就被卸载了。
这样做的目的是为了在没有硬盘的情况下,DTV还可以播放,因为DTV数据库不在硬盘上,但flash空间有限,放不下所有数据库。但Database区只有256K,太小,以至于不能以可写格式jffs2写入,而cramfs格式又不支持写操作。
所以采用以下策略:
1、 开机时将DTV数据库读到内存中,并马上卸载该区;
2、 对数据库的修改在内存中进行;
3、 在数据库进行了修改操作后,再整体将数据从内存复制到flash的Database区;
将修改了的数据库复制到flash的操作称作同步数据库。
DTV数据库只在搜索频道后被修改,所以同步数据库操作只在搜台结束后进行。
同步数据库由一脚本来完成,脚本位于app目录下:pb1100/bin/syncdb.sh
脚本内容:
cd /rd
rm -r cramfs
rm hd_db.cramfs
mkdir cramfs
cp -r data/ cramfs/
cp -r db/msqldb/FLASH_DB/ cramfs/
mkcramfs -r b cramfs hd_db.cramfs
dd if=hd_db.cramfs of=/dev/mtdblock7
cd –
系统启动顺序
经过以上步骤,盒子应该是弄好了,可以启动了。这里说一下盒子在启动时候,各个应用程序和脚本的执行顺序。
盒子的内核在bios的引导下启动后,将把本地的文件系统挂载进来。etc/rc.d/rcS.d目录下的文件是与PushTV系统相关的最早执行的脚本,S10checkroot.sh、S35mountall.sh和S40networking分别指向etc/init.d/目录下的checkroot.sh、mountall.sh和networking(这个顺序也是它们执行的顺序,这个顺序由S后面的数值决定,数值越小越早执行)。
各个脚本完成的功能:
n Checkroot.sh
n Mountall.sh
1) 在内存中建立各个目录,包括数据库文件存放的目录;
2) 启动Loader.out,这时在前面板会出现“FE”字样,此时快速按“MENU-上-下-左-右”键,将进行应用程序的更新操作;
3) 从flash上将DTV的数据库文件复制过来,对DTV数据库的操作将在内存中进行,操作完成后将烧写到flash的database区;
4) 加载(mount)flash的Applications分区(mtdblock8);
5) 加载(insmod)几个驱动;
n Networking
启动网络;
这三个脚本执行完后,系统会运行脚本etc/inittab脚本,该脚本将运行/app/bin/autostart.sh脚本。
autostart.sh脚本里完成以下操作:
1、 加载驱动;
2、 设置全局变量;
3、 启动flash和硬盘的校验程序,这里的flash校验程序只检查database区,校验工作由pushtvad_init.out完成;
4、 启动PushTV应用程序。