1、开发平台

虚拟机:VMware 12

操作系统:Ubuntu 14.04 64bit

2、准备ARM交叉编译工具包

编译uboot和linux kernel都需要ARM交叉工具链支持,这里使用Linaro提供的交叉编译工具。下载地址为:http://releases.linaro.org/

注意:如果主机是64bit,请选择64位的交叉编译器工具链,32bit的主机选择32位的交叉工具链。

The Linaro Toolchain Working Group is pleased to announce this quarter’s release of the Linaro Toolchain Binaries, a pre-built version of Linaro GCC and Linaro GDB that runs on generic Linux or Windows and targets the glibc Linaro Engineering Build.

Beginning 2014.11, Linaro is changing the layout and structure of its prebuilt toolchain binary releases. 2014.11 is the first release built with ABE, adding more maintainable code base and automatic testing. For further details on ABE, please visit https://wiki.linaro.org/ABE.

The folder names above describe the target triplets, i.e. the system on which you want your programs/applications to run. For more details on triplets, please click here.

Inside each folder is also a manifest.txt file further describing the target and host systems meant for the toolchain, plus source component versions.

Essentially, the main folder contents are as follows:

aarch64-linux-gnu

· gcc-linaro-*x86_64_aarch64-linux-gnu.tar.xz

o Linux 64-bit binaries for the Aarch64 Linux cross-toolchain

· gcc-linaro-*i686-mingw32_aarch64-linux-gnu.tar.xz

o Windows 32-bit binaries for the Aarch64 Linux cross-toolchain

aarch64-none-elf

· gcc-linaro-*x86_64_aarch64-elf.tar.xz

o Linux 64-bit binaries for the Aarch64 bare-metal cross-toolchain

· gcc-linaro-*i686-mingw32_aarch64-elf.tar.xz

o Windows 32-bit binaries for the Aarch64 bare-metal cross-toolchain

aarch64_be-linux-gnu

· gcc-linaro-*x86_64_aarch64_be-linux-gnu.tar.xz

o Linux 64-bit binaries for the Aarch64 Linux Big Endian cross-toolchain

· gcc-linaro-*i686-mingw32_aarch64_be-linux-gnu.tar.xz

o Windows 32-bit binaries for the Aarch64 Linux Big Endian cross-toolchain

aarch64_be-none-elf

· gcc-linaro-*x86_64_aarch64_be-elf.tar.xz

o Linux 64-bit binaries for the Aarch64 bare-metal Big Endian cross-toolchain

· gcc-linaro-*i686-mingw32_aarch64_be-elf.tar.xz

o Windows 32-bit binaries for the Aarch64 bare-metal Big Endian cross-toolchain

arm-linux-gnueabi

· gcc-linaro-*x86_64_arm-linux-gnueabi.tar.xz

o Linux 64-bit binaries for the ARMv7 Linux soft float cross-toolchain

· gcc-linaro-*i686-mingw32_arm-linux-gnueabi.tar.xz

o Windows 32-bit binaries for the ARMv7 Linux soft float cross-toolchain

arm-linux-gnueabihf

· gcc-linaro-*x86_64_arm-linux-gnueabihf.tar.xz

o Linux 64-bit binaries for the ARMv7 Linux hard float cross-toolchain

· gcc-linaro-*i686-mingw32_arm-linux-gnueabihf.tar.xz

o Windows 32-bit binaries for the ARMv7 Linux hard float cross-toolchain

arm-none-eabi

· gcc-linaro-*x86_64_arm-eabi.tar.xz

o Linux 64-bit binaries for the ARMv7 bare-metal cross-toolchain

· gcc-linaro-*i686-mingw32_arm-eabi.tar.xz

o Windows 32-bit binaries for the ARMv7 bare-metal cross-toolchain

armeb-linux-gnueabihf

· gcc-linaro-*x86_64_armeb-linux-gnueabihf.tar.xz

o Linux 64-bit binaries for the ARMv7 Linux Big Endian hard float cross-toolchain

· gcc-linaro-*i686-mingw32_armeb-linux-gnueabihf.tar.xz

o Windows 32-bit binaries for the ARMv7 Linux Big Endian hard float cross-toolchain

armeb-none-eabi

· gcc-linaro-*x86_64_armeb-eabi.tar.xz

o Linux 64-bit binaries for the ARMv7 bare-metal Big Endian cross-toolchain

· gcc-linaro-*i686-mingw32_armeb-eabi.tar.xz

o Windows 32-bit binaries for the ARMv7 bare-metal Big Endian cross-toolchain

NOTE

· The binary source package is no longer distributed as the components are now archived at http://abe.tcwglab.linaro.org/snapshots and downloaded automatically based on manifest.txt when (re)building with ABE.

· The source package releases for the individual components are still at http://releases.linaro.org/latest/components/toolchain. Select the component (e.g. gcc, glibc, binutils, gdb) as necessary.

· The binary tarball has been splitted into 3 parts. As a result, you can install only the parts needed:

o gcc-linaro-*.tar.xz – the compiler and tools

o runtime-linaro-*.tar.xz – runtime libraries needed on the target

o sysroot-linaro-*.tar.xz – sysroot (a set of libraries and headers to develop against)

· Beginning 2014.11, sysroots will use the latest glibc release provided by Linaro engineers in order that users get the latest features and optimizations in the system libraries.

· Eglibc 2.15 compatible sysroots will no longer be released. Users that require Eglibc 2.15 sysroots that need the latest Linaro GCC compiler should use the previous quarterly released sysroot.

· x86 (32-bit) Linux host toolchains are no longer provided. x86_64 (64-bit) Linux host toolchains are provided instead.

· Soft-float targeted toolchains are no longer supported.

笔者使用的ARM交叉工具链版本为gcc-linaro-6.1.1-2016.08-x86_64_arm-linux-gnueabi.tar.xz

下载地址为:

http://releases.linaro.org/components/toolchain/binaries/6.1-2016.08/arm-linux-gnueabi/gcc-linaro-6.1.1-2016.08-x86_64_arm-linux-gnueabi.tar.xz

3、安装步骤

3.1、Ubuntu14.04 64bit系统下安装标准的C开发环境

sudo apt-get install gcc g++ libgcc1 libg++ make gdb

或者 sudo apt-get install build-essential

3.2、下载gcc-linaro-6.1.1-2016.08-x86_64_arm-linux-gnueabi.tar.xz

1> 在/usr/local/文件夹下建立名为ARM-toolchain的文件夹

$ sudo mkdir /usr/local/ARM-toolchain

2> 下载gcc-linaro-6.1.1-2016.08-x86_64_arm-linux-gnueabi.tar.xz

$ cd /usr/local/ARM-toolchain

sudo wget http://releases.linaro.org/components/toolchain/binaries/6.1-2016.08/ arm-linux-gnueabi/gcc-linaro-6.1.1-2016.08-x86_64_arm-linux-gnueabi.tar.xz

3.3、安装gcc-linaro-6.1.1-2016.08-x86_64_arm-linux-gnueabi

解压gcc-linaro-6.1.1-2016.08-x86_64_arm-linux-gnueabi.tar.xz

$ xz –d gcc-linaro-6.1.1-2016.08-x86_64_arm-linux-gnueabi.tar.xz

$ tar xvf gcc-linaro-6.1.1-2016.08-x86_64_arm-linux-gnueabi.tar

3.4、修改环境变量,把交叉编译器的路径加入到PATH

修改/etc/bash.bashrc文件(此文件只对当前用户适用)

$sudo gedit /etc/bash.bashrc

然后在文件的末尾空白处加入一下代码:

Add ARM toolschain path

if [ -d /usr/local/ARM-toolchain/gcc-linaro-6.1.1-2016.08-x86_64_arm-linux-gnueabi ] ; then

PATH= /usr/local/ARM-toolchain/gcc-linaro-6.1.1-2016.08-x86_64_arm-linux-gnueabi/bin:"${PATH}"

fi

3.5、使新的环境变量生效(不用重启电脑)

$ source /etc/bash.bashrc

3.6. 检查是否将路径加入到PATH:

$ echo $PATH

若显示的内容中含有:/usr/local/ARM-toolchain/gcc-linaro-6.1.1-2016.08-x86_64_arm-linux-gnueabi/bin 说明已经将交叉编译器的路径加入PATH。

至此,交叉编译环境安装完成。

3.7. 测试是否安装成功

$ arm-linux-gnueabi-gcc -v

执行上面的命令,显示arm-linux-gnueabi-gcc -v信息和版本:

$ arm-linux-gnueabi-gcc -v

Using built-in specs.

COLLECT_GCC=arm-linux-gnueabi-gcc

COLLECT_LTO_WRAPPER=/usr/local/ARM-toolchain/gcc-linaro-6.1.1-2016.08-x86_64_arm-linux-gnueabi/bin/../libexec/gcc/arm-linux-gnueabi/6.1.1/lto-wrapper

Target: arm-linux-gnueabi

Configured with: /home/tcwg-buildslave/workspace/tcwg-make-release/label/docker-trusty-amd64-tcwg/target/arm-linux-gnueabi/snapshots/gcc-linaro-6.1-2016.08/configure SHELL=/bin/bash --with-mpc=/home/tcwg-buildslave/workspace/tcwg-make-release/label/docker-trusty-amd64-tcwg/target/arm-linux-gnueabi/_build/builds/destdir/x86_64-unknown-linux-gnu --with-mpfr=/home/tcwg-buildslave/workspace/tcwg-make-release/label/docker-trusty-amd64-tcwg/target/arm-linux-gnueabi/_build/builds/destdir/x86_64-unknown-linux-gnu --with-gmp=/home/tcwg-buildslave/workspace/tcwg-make-release/label/docker-trusty-amd64-tcwg/target/arm-linux-gnueabi/_build/builds/destdir/x86_64-unknown-linux-gnu --with-gnu-as --with-gnu-ld --disable-libstdcxx-pch --disable-libmudflap --with-cloog=no --with-ppl=no --with-isl=no --disable-nls --enable-c99 --enable-gnu-indirect-function --with-tune=cortex-a9 --with-arch=armv7-a --with-fpu=vfpv3-d16 --with-float=softfp --with-mode=thumb --disable-multilib --enable-multiarch --with-build-sysroot=/home/tcwg-buildslave/workspace/tcwg-make-release/label/docker-trusty-amd64-tcwg/target/arm-linux-gnueabi/_build/sysroots/arm-linux-gnueabi --enable-lto --enable-linker-build-id --enable-long-long --enable-shared --with-sysroot=/home/tcwg-buildslave/workspace/tcwg-make-release/label/docker-trusty-amd64-tcwg/target/arm-linux-gnueabi/_build/builds/destdir/x86_64-unknown-linux-gnu/arm-linux-gnueabi/libc --enable-languages=c,c++,fortran,lto --enable-checking=release --disable-bootstrap --build=x86_64-unknown-linux-gnu --host=x86_64-unknown-linux-gnu --target=arm-linux-gnueabi --prefix=/home/tcwg-buildslave/workspace/tcwg-make-release/label/docker-trusty-amd64-tcwg/target/arm-linux-gnueabi/_build/builds/destdir/x86_64-unknown-linux-gnu

Thread model: posix

gcc version 6.1.1 20160711 (Linaro GCC 6.1-2016.08)

一、sd启动

将u-boot镜像写入SD卡,将SD卡通过读卡器接上电脑(或直接插入笔记本卡槽),通过"cat /proc/partitions"找出SD卡对应的设备,我的设备节点是/dev/sdb.(内存卡的节点)。

当有多个交叉编译器是,不方便设置环境变量时,可以在编译命令中指定交叉编译器,具体如下:在源码中操作以下步骤:

make distclean

make ARCH=arm CROSS_COMPILE=/opt/FriendlyARM/toolschain/4.5.1/bin/arm-none-linux-gnueabi- mrproper

make ARCH=arm CROSS_COMPILE=/opt/FriendlyARM/toolschain/4.5.1/bin/arm-none-linux-gnueabi- tiny210_config

make ARCH=arm CROSS_COMPILE=/opt/FriendlyARM/toolschain/4.5.1/bin/arm-none-linux-gnueabi- all spl

编译出tiny210-uboot.bin,注意交叉编译工具路径

执行下面的命令
$sudo dd iflag=dsync oflag=dsync if=tiny210-uboot.bin of=/dev/sdb seek=1

把内存卡插入开发板,使用串口工具设置环境变量:

setenv gatewayip 192.168.1.1 (电脑网关)
setenv ipaddr 192.168.1.102 (开发板ip,不要与虚拟机和电脑ip冲突)
setenv netmask 255.255.255.0
setenv serverip 192.168.1.10 (虚拟机ip)

saveenv

二、nand启动

烧写Uboot:

通过SD卡启动的u-boot for tiny210 将u-boot镜像写入nandflash

在虚拟机下重启tftp sudo service tftpd-hpa restart

开发板终端下执行下面的命令:

[FriendlyLEG-TINY210]# tftp 21000000 tiny210-uboot.bin

[FriendlyLEG-TINY210]# nand erase.chip

[FriendlyLEG-TINY210]# nand write 21000000 0 3c1f4 (写入长度)

内核的烧写位置是0x600000开始的区域,文件系统烧写位置为0xe00000开始的区域。

三、烧写内核:

重新设置环境变量:

setenv gatewayip 192.168.1.1 (电脑网关)
setenv ipaddr 192.168.1.102 (开发板ip,不要与虚拟机和电脑ip冲突)
setenv netmask 255.255.255.0
setenv serverip 192.168.1.10 (虚拟机ip)

saveenv

在/svn/linux-3.0.8 源码目录下make uImage,将uImage拷贝到tftp目录下

[FriendlyLEG-TINY210]#tftp 21000000 uImage          //下载文件到内存

[FriendlyLEG-TINY210]#nand erase 600000 f200000               //擦写相应的nand

[FriendlyLEG-TINY210]#nand write 21000000 600000 b03c280(写入长度) //写到nand

TFTP服务器配置:

sudo apt-get install xinetd

sudo apt-get install tftp-hpa tftpd-hpa

配置:

1: 在/etc/xinetd.d/目录下创建tftp配置文件

2: touch /etc/xinetd.d/tftp

3:

service tftp

{

socket_type = dgram

protocol = udp

wait = yes

user = root

server = /usr/sbin/in.tftpd

server_args = -s /var/tftpboot/

disable = no

per_source = 11

cps = 100 2

flags = IPv4

}

4: 创建tftp下载目录:

mkdir -p /var/tftpboot/

sudo chmod 777 /var/tftpboot

echo “iloveyou” >> /var/tftpboot/demo

测试:

tftp localhost

tftp 127.0.0.1

get demo

quit

四、启动参数

设置bootargs参数
1:如果用yaffs2文件系统
setenv bootargs noinitrd root=/dev/mtdblock4 rootfstype=yaffs2 rw console=ttySAC0,115200 init=/linuxrc mem=64M

设置自启动参数bootcmd 

setenv bootcmd nand read 21000000 80000 (nand起始地址)22e800 (nand写入长度)\; bootm 21000000

烧写命令如下:

[FriendlyLEG-TINY210]#tftp 21000000 rootfs_android.img            //下载文件到内存

[FriendlyLEG-TINY210]#nand erase e00000 f200000               //擦写相应的nand

[FriendlyLEG-TINY210]#nand write.yaffs 21000000 e00000 b03c280       //写到nand

记住yaffs镜像是包含OOB数据的,所以写入NAND Flash的数据长度应该是2112(=2048 + 64)字节的整数倍。

2:如果用NFS烧写文件系统
setenv bootargs root=/dev/nfs rw nfsroot=192.168.1.10(虚拟机ip):/home/xyp/nfsroot/rootfs ip=192.168.1.102(开发板ip):192.168.1.10(虚拟机ip):192.168.1.1:255.255.255.0::eth0:off console=ttySAC0,115200 init=/linuxrc

Setenv bootcmd nand read 21000000 600000 20b334 \; bootm 21000000

Saveenv

2.1 nfs配置

Sudo apt-get install nfs-kernel-server 配置nfs

Sudo vi /etc/exports添加/home/ly/nfs *(rw,sync,no_root_squash)

重启nfs服务,使配置生效:sudo /etc/init.d/nfs-kernel-server restart

2、构建根文件按系统
2.1、建立根文件系统目录
在/home/ly下创建目录system,新建建立根文件系统目录的脚本文件 create_rootfs_bash,使用命令sudo chmod +x create_rootfs_bash改变文件的可执行权限,./create_rootfs_bash运行脚本,就完成了根文件系统目录的创建。

文件系统目录脚本文件:

!/bin/sh

echo "------Create rootfs directons start...--------"
mkdir rootfs
cd rootfs

echo "--------Create root,dev....----------"
mkdir root dev etc boot tmp var sys proc lib mnt home usr
mkdir etc/init.d etc/rc.d etc/sysconfig
mkdir usr/sbin usr/bin usr/lib usr/modules

echo "make node in dev/console dev/null"

mknod -m 600 dev/console c 5 1
mknod -m 600 dev/null c 1 3
mkdir mnt/etc mnt/jffs2 mnt/yaffs mnt/data mnt/temp

mkdir var/lib var/lock var/run var/tmp

chmod 1777 tmp
chmod 1777 var/tmp

echo "-------make direction done---------"

2.2建立动态链接库
动态链接库直接用友善之臂的,先解压友善之臂的根文件包,拷贝lib的内容到新 建的根文件目录lib内。
cd /opt/studyarm (压缩包存放位置)

tar –zxvf root_qtopia.tgz –C /opt/studyarm (输出目录)
cp –rf /opt/studyarm/root_qtopia/lib/* /home/ly/system/rootfs/lib/

2.3交叉编译Bosybox
Bosybox是一个遵循GPLv2协议的开源项目,它在编写过程总对文件大小进行优化,并考虑了系统资源有限(比如内存等)的情况,使用Busybox可以自动生成根文件系统所需的bin、sbin、usr目录和linuxrc文件。
1、解压busybox
cd /mnt/hgfs/share (压缩包存放位置)
tar –zxvf busybox-1.13.3.tar.tgz –C /opt/studyarm (输出目录)
2、进入源码,修改Makefile文件:
cd /opt/studyarm/busybox-1.13.3
修改:
CROSS_COMPILE ?=arm-linux- //第164行
ARCH ?=arm //第189行

3、配置busybox
输入make menuconfig进行配置
(1)、Busybox Settings--->
General Configuration--->
[*] Show verbose applet usage messages
[*] Store applet usage messages in compressed form
[*] Support –install [-s] to install applet links at runtime
[*] Enable locale support(system needs locale for this to work)
[*] Support for –long-options
[*] Use the devpts filesystem for unix98 PTYs
[*] Support writing pidfiles
[*] Runtime SUID/SGID configuration via /etc/busybox.config
[*] Suppress warning message if /etc/busybox.conf is not readable
Build Options--->

  [*] Build BusyBox as a static binary(no shared libs) 

[*] Build with Large File Support(for accessing files>2GB)
Installation Options->
[]Don’t use /usr
Applets links (as soft-links) --->
(./_install) BusyBox installation prefix
Busybox Library Tuning --->
(6)Minimum password legth
(2)MD5:Trade Bytes for Speed
[*]Fsater /proc scanning code(+100bytes)
[*]Command line editing
(1024)Maximum length of input
[*] vi-style line editing commands
(15) History size
[*] History saving
[*] Tab completion
[*]Fancy shell prompts
(4) Copy buffer size ,in kilobytes
[*]Use ioctl names rather than hex values in error messages
[*]Support infiniband HW
(2)、Linux Module Utilities--->
(/lib/modules)Default directory containing modules
(modules.dep)Default name of modules.dep
[*] insmod
[*] rmmod
[*] lsmod
[*] modprobe
-----options common to multiple modutils
[ ] support version 2.2/2.4 Linux kernels
[*]Support tainted module checking with new kernels
[*]Support for module .aliases file
[*] support for modules.symbols file

如果出现错误,直接找到相应的函数,取消该选项,在make menuconfig下用/查找,空格键添加/取消选项内容。

4、在busybox中配置对dev下设备类型的支持

mdev是busybox自带的一个简化版的udev,适合于嵌入式的应用埸合。其具有使用简单的特点。它的作用,就是在系统启动和热插拔或动态加载驱动程序时,自动产生驱动程序所需的节点文件。在以busybox为基础构建嵌入式linux的根文件系统时,使用它是最优的选择。下面的选项将增加对mdev的支持。
Linux System Utilities --->

[*]Support /etc/mdev.conf          
[*]Support command execution at device addition/removal

5、编译busybox
编译busybox到指定目录:
cd /opt/studyarm/busybox-1.13.3
make CONFIG_PREFIX=/home/ly/system/rootfs install

在rootfs目录下会生成目录bin、sbin、usr和文件linuxrc的内容。

6、建立etc目录下的配置文件
1、etc/mdev.conf文件,内容为空。
2、拷贝主机etc目录下的passwd、group、shadow文件到rootfs/etc 目录下。
3、etc/sysconfig目录下新建文件HOSTNAME,内容为”LYliyan”。
4、etc/inittab文件:

etc/inittab

::sysinit:/etc/init.d/rcS
::askfirst:-/bin/sh
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a –r
7、etc/init.d/rcS文件:

!/bin/sh

PATH=/sbin:/bin:/usr/sbin:/usr/bin
runlevel=S
prevlevel=N
umask 022
export PATH runlevel prevlevel

echo "----------munt all----------------"
mount -a

echo /sbin/mdev>/proc/sys/kernel/hotplug
mdev -s

echo "*"
echo "*Studying ARM"
echo "Kernel version:linux-2.6.29.1"
echo "Student:Feng dong rui"
echo "Date:2009.07.15"
echo ""

/bin/hostname -F /etc/sysconfig/HOSTNAME
使用以下命令改变rcS的执行权限:
sudo chmod +x rcS
8、etc/fstab文件:

device mount-point type option dump fsck order

proc /proc proc defaults 0 0
none /tmp ramfs defaults 0 0
sysfs /sys sysfs defaults 0 0
mdev /dev ramfs defaults 0 0
9、 etc/profile文件:

Ash profile

vim:syntax=sh

No core file by defaults

ulimit -S -c 0>/dev/null 2>&1

USER="id -un"
LOGNAME=$USER
PS1='[\u@\h=W]#'
PATH=$PATH
HOSTNAME='/bin/hostname'
export USER LOGNAME PS1 PATH

10、制作根文件系统映像文件
使用以下命令安装好yaffs文件系统制作工具:
cd /mnt/hgfs/share
tar –zxvf mkyaffs2image.tgz –C /
在/opt/studyarm目录下,使用命令mkyaffs2image rootfs rootfs.img 生成根文件系统映像文件。

注意:

制作镜像提供的有两个工具,我的开发板是1G Flash的所以应该选用mkyaffs2image-128M的,选用mkyaffs2image会出现烧写文件系统不成功的错误。提供的文档中rootfs_rtm_210这个文件系统也是可用的

随机映射使用 -P 参数时,Docker 会随机映射一个端口到内部容器开放的网络端口示例:docker run -d -P nginx

指定端口使用 -p 参数时,可以指定要映射的端口,并且在一个指定的端口上只可以绑定一个容器。支持的格式有:IP:HostPort:ContainerPortIP:ContainerPortHostPort:ContainerPort示例:将本机 8080 端口映射到容器的 80 端口:docker run -d -p 8080:80 nginx

查看端口映射docker port CONTAINER

DOCKER 给运行中的容器添加映射端口

方法1:
获得容器IP:
docker inspect container_name | grep IPAddress

iptable转发端口
iptables -t nat -A DOCKER -p tcp --dport 8001 -j DNAT --to-destination 172.17.0.19:8000

方法2:
提交一个运行中的容器为镜像:docker commit containerid foo/live
运行镜像并添加端口:docker run -d -p 8000:80 foo/live /bin/bash

dede系统换LMXCMS 后模板风格切换不生效。经过分析调试
文件 lmxcms1.41\class\parse.class.php
构造函数

public function __construct(&$smarty){
    global $config;
    $this->config = $config;
    $this->smarty = $smarty;
    //修改smarty配置为前台
    defined('TEMDIR') || define('TEMDIR',$GLOBALS['public']['default_temdir']); //电脑模板目录
    defined('COMPILE_DIR') || define('COMPILE_DIR','index'); //电脑编译目录
    defined('COMPILE_CACHE_DIR') || define('COMPILE_CACHE_DIR','index'); //电脑编译缓存目录
    $this->smarty->template_dir = $this->config['template'].TEMDIR.'/'; //模板路径
    $this->smarty->compile_dir=$this->config['smy_compile_dir'].COMPILE_DIR.'/'; //编译文件路径
    $this->smarty->cache_dir = $this->config['smy_cache_dir'].COMPILE_CACHE_DIR.'/'; //缓存目录
}

是通过 defined('TEMDIR') 定义判断,已定义值有定义的值,否则取后台模板风格

查看首页文件 index.php
lmxcms1.41\index.php

define('LMXCMS',TRUE);
define('RUN_TYPE','index');
define('TEMDIR','default'); //电脑模板目录
define('COMPILE_DIR','index'); //电脑编译目录
define('COMPILE_CACHE_DIR','index'); //电脑编译缓存目录
require dirname(__FILE__).'/inc/config.inc.php';
require dirname(__FILE__).'/inc/run.inc.php';

第9行 define('TEMDIR','default'); //电脑模板目录
定义了默认风格导致后台切换无效。

处理方法 注释第9行代码
//define('TEMDIR','default'); //电脑模板目录
问题解决

一、什么是BGP
BGP全称是Border Gateway Protocol, 对应中文是边界网关协议。这个名字比较抽象,而维基中文的解释我觉得比较好(维基英文甚至都没有类似的解释)。BGP是互联网上一个核心的去中心化自治 路由协议。从这个解释来看,首先这是一个用于互联网(Internet)上的路由协议。它的地位是核心的(目前是最重要的,互联网上唯一使用的路由协议),它的目的是去中心化,以达到各个网络自治。不过还是有点抽象?

先看看几个相关的概念:

AS(Autonomous system):自治系统,指在一个(有时是多个)组织管辖下的所有IP网络和路由器的全体,它们对互联网执行共同的路由策略。也就是说,对于互联网来说,一个AS是一个独立的整体网络。而BGP实现的网络自治也是指各个AS自治。每个AS有自己唯一的编号。
IGP(Interior Gateway Protocol):内部网关协议,在一个AS内部所使用的一种路由协议。一个AS内部也可以有多个路由器管理多个网络。各个路由器之间需要路由信息以知道子网络的可达信息。IGP就是用来管理这些路由。代表的实现有RIP和OSPF。
EGP(Exterior Gateway Protocol):外部网关协议,在多个AS之间使用的一种路由协议,现在已经淘汰,被BGP取而代之。
由于BGP就是为了替换EGP而创建,它的地位与EGP相似。但是BGP也可以应用在一个AS内部。因此BGP又可以分为IBGP(Interior BGP :同一个AS之间的连接)和EBGP(Exterior BGP:不同AS之间的BGP连接)。既然EGP已经被替代了,那EBGP的存在比较好理解,但是IGP协议都还活得好好的(这里指的是OSPF),那IBGP的意义何在?IGP的协议是针对同一个AS网络来设计的,一个自治网络的规模一般都不大,所以设计的时候就没有考虑大规模网络的情况。而当一个自治网络足够大时,OSPF存在性能瓶颈(后面会说明)。BGP本身就是为了在Internet工作,其设计就是为了满足大型网络的要求,所以大型私有IP网络内部可以使用IBGP。总的来说,这几类路由协议,小规模私有网络IGP,大规模私有网络IBGP,互联网EBGP。

图片

二、为什么需要BGP
BGP号称是使互联网工作的协议,看起来似乎很重要,为什么平常的生活中很少接触呢?似乎云里面也不怎么提BGP,我们来看看原因吧。

假设小明正在搭建一个云环境,提供虚拟机服务。

图片

云里的虚机需要有互联网访问能力,于是小明向ISP(Internet service provider)申请了一个公网IP,这里的ISP可以是联通,移动,电信等等。虚机们可以通过路由器的NAT/PAT(Network / Port address translation)将自己的私网IP转换成这个公网IP,然后小明在云中路由器上将ISP router的地址设为默认路由。这样地址转换之后的IP包都发送到了ISP,进而发送到了互联网(这也是我们家用路由器能让家里的设备上网的原理)。这样小明的1.0版本云简单上线。这里小明不需要BGP。

版本上线之后怎么办?当然是开发下一版本!下一版本的需求是可以通过互联网访问虚机(也就是从互联网访问我们家里的电脑)。这个也不难,可以通过端口转发(Port Forward),将虚机的一个端口与公网IP的端口进行映射。例如将虚机的22端口映射到公网IP的1122端口,那么可以通过互联网ssh到公网IP:1122,登陆虚机。这部分工作仍然是在小明的云中路由器完成。这样,小明的2.0版本云上线了,这里小明还是不需要BGP。

图片

2.0版本虽然支持了从互联网访问虚机,但是还有问题:

1、每个虚机每开放一个端口都需要映射一次
2、公网IP的端口是有限的
为了解决这些问题,小明向联通申请了一些公网IP地址,对于需要从外网访问的虚机,直接给它们分配公网IP。这样小明的3.0版本云上线了,这里小明还是不需要BGP。因为:

1、联通是小明云唯一连接的ISP,小明只能通过联通访问互联网,所以小明的云中路由器的默认路由只能设置成ISP 路由器的地址。
2、小明云里面的公网IP都是联通分配的,联通当然知道该从哪个IP地址作为下一跳去访问那些IP地址。
图片

联通的IP毕竟是有限的,而且联通还老是断线。这都发布3个版本了,小明决定干一票大的。

首先,小明向IANA(Internet Assigned Numbers Authority)申请了自己的公网IP池。因为有了自己的公网IP,也必须要考虑申请AS号。AS号是一个16bit的数字,全球共用这60000多个编号。1 – 64511 是全球唯一的,而 64512 – 65535 是可以自用的,类似于私网网段。每个自治网络都需要申请自己的AS编号,联通的AS号是9800。

然后,小明分别向联通和电信买了线路,这样就算联通断线还能用电信。

那现在问题来了:

1、联通或者电信怎么知道小明申请的公网IP是什么。换言之,我现在拨号拨进了联通宽带,我怎么才能访问到小明云的公网IP?
2、小明的云中路由器的默认路由该设置到联通的ISP路由器,还是电信的?
终于,在小明的4.0版本云上,小明需要用BGP了。通过BGP,小明可以将自己云中的路由信息发送到联通,电信,这样ISP就知道了改如何访问小明的公网虚拟机,也就是说我们普通的使用者通过ISP,能访问到小明的网络。另一方面,通过在云中运行BGP服务,小明可以管理云中路由器的默认路由。

总的来说,要是你之前没有听过或者用过BGP,只能说你的网络还没有到那个规模 :)

三、BGP协议
BGP可以说是最复杂的路由协议。它是应用层协议,其传输层使用TCP,默认端口号是179。因为是应用层协议,可以认为它的连接是可靠的,并且不用考虑底层的工作,例如fragment,确认,重传等等。BGP是唯一使用TCP作为传输层的路由协议,其他的路由协议可能都还到不了传输层。

TCP连接的窗口是65K字节,也就是说TCP连接允许在没有确认包的情况下,连续发送65K的数据。而其他的路由协议,例如EIGRP和OSPF的窗口只有一个数据包,也就是说前一个数据包收到确认包之后,才会发送下一个数据包。当网络规模巨大时,需要传输的数据也相应变大,这样效率是非常低的。这也是它们不适合大规模网络的原因。而正是由于TCP可以可靠的传输大量数据,且互联网的路由信息是巨大的,TCP被选为BGP的传输层协议,并且BGP适合大规模网络环境。

和大部分协议一样,BGP的数据由header和data组成。Header有19个字节,所有的BGP数据的Header格式是一样的。

图片

Marker有16个字节长,存储着同步信息和加密信息。Length2个字节,包含header在内的长度。Type1个字节,表示当前BGP数据的类型,具体有4类:

Open(code 1):TCP连接建立之后,BGP发送的第一个包。收到Open之后,BGP peer会发送一个Keepalive消息以确认Open。其他所有的消息都只会在Open消息确认之后,并且BGP连接已经建立之后发送。
Update(code 2):BGP连接后的首次Update会交换整个BGP route table,之后的Update只会发送变化了的路由信息。所以说BGP是动态的传输路由消息的变化。
Notification(code 3):出错时发送的消息,这个消息一旦发送,BGP连接将会中断。
Keepalive(code 4):没有data,只有header。用来保持BGP连接,通常是1/3的BGP session hold time。默认是60秒,如果hold time是0,不会发送Keepalive。
每一种BGP数据的data都不相同,这些都由网络设备商实现了,简单看一下Open和Update的data吧。

图片

BGP Open 数据,由于是发送的第一个包,因此就是一些配置信息。例如自身的AS号,BGP连接的超时时间(hold time),BGP id。

图片

BGP Update 数据,主要就是交换Network Layer Reachability Information (NLRI)。一个Update数据包里面只会有一条path的路由信息,因此只有一组path attribute,但是路由可以有多条。具体的说,一个BGP router可能连接了多个BGP peer router,那么它在发送BGP Update数据时,一次只会发送一个它的BGP peer router的信息。(欢迎关注公众号:网络工程师阿龙)

四、BGP如何工作
BGP是一种路径矢量协议(Path vector protocol)的实现。因此,它的工作原理也是基于路径矢量。首先说明一下,下面说的BGP route指的是BGP自己维护的路由信息,区分于设备的主路由表,也就是我们平常看见的那个路由表。BGP route是BGP协议传输的数据,并存储在BGP router的数据库中。(欢迎关注公众号:网络工程师阿龙) 并非所有的BGP route都会写到主路由表。每条BGP route都包含了目的网络,下一跳和完整的路径信息。路径信息是由AS号组成,当BGP router收到了一条 路由信息,如果里面的路径包含了自己的AS号,那它就能判定这是一条自己曾经发出的路由信息,收到的这条路由信息会被丢弃。

这里把每个BGP服务的实体叫做BGP router,而与BGP router连接的对端叫BGP peer。每个BGP router在收到了peer传来的路由信息,会存储在自己的数据库,前面说过,路由信息包含很多其他的信息,BGP router会根据自己本地的policy结合路由信息中的内容判断,如果路由信息符合本地policy,BGP router会修改自己的主路由表。本地的policy可以有很多,(欢迎关注公众号:网络工程师阿龙) 举个例子,如果BGP router收到两条路由信息,目的网络一样,但是路径不一样,一个是AS1->AS3->AS5,另一个是AS1->AS2,如果没有其他的特殊policy,BGP router会选用AS1->AS2这条路由信息。policy还有很多其他的,可以实现复杂的控制。

除了修改主路由表,BGP router还会修改这条路由信息,将自己的AS号加在BGP数据中,将下一跳改为自己,并且将自己加在路径信息里。在这之后,这条消息会继续向别的BGP peer发送。而其他的BGP peer就知道了,可以通过指定下一跳到当前BGP router,来达到目的网络地址。

所以说,BGP更像是一个可达协议,可达信息传来传去,本地根据收到的信息判断决策,再应用到路由表。