Jul 8, 2013
Technology1. 下载并交叉编译u-boot。
新版本的u-boot我加载后总有问题,2009.11版则可以顺利通过编译和测试。
$ wget ftp://ftp.denx.de/pub/u-boot/u-boot-2009.11.tar.bz2
$ tar xjvf u-boot-2009.11.tar.bz2
$ cd u-boot-2009.11
$ make versatilepb_config arch=ARM CROSS_COMPILE=arm-none-eabi-
$ make all arch=ARM CROSS_COMPILE=arm-none-eabi-
编译完成后会在目录下生成u-boot.bin和u-boot文件。
2. 运行u-boot.bin:
$ qemu-system-arm -M versatilepb -kernel u-boot.bin -nographic
如果采用-nographic来运行qemu-system-arm,终端将无法再响应任何系统输入譬如Ctrl+c/ctrl+d_,要终止qemu-system-arm就只能查到进程号再kill。所以我一般不带-nographic选项,启动后ctrl+alt+2去看serial0输出,保留在终端窗口直接ctrl+c杀死qemu-sytem-arm进程的权力。
3. 用u-boot引导镜像文件:
改动上一篇文章里用于构建启动镜像的linker.ld文件,因为u-boot.bin文件大小的缘故,我们需要把启动镜像的起始地址整体上移.
$ ls -l -h u-boot.bin
-rwxr-xr-x 1 Trusty root 85K Jul 8 15:57 u-boot.bin
linker.ld文件里, 0x100000,这个大小相比于85K显然已经足够。
ENTRY(_Start)
SECTIONS
{
. = 0x100000;
startup : { startup.o(.text)}
.data : {*(.data)}
.bss : {*(.bss)}
. = . + 0x500;
sp_top = .;
}
按上一章的编译方法生成output.bin,不再重述。
使用mkimage工具创建u-boot可识别的image文件:
$ mkimage -A arm -C none -O linux -T kernel -d output.bin -a 0x00100000 -e 0x00100000 output.uimg
Image Name:
Created: Mon Jul 8 16:04:11 2013
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 152 Bytes = 0.15 kB = 0.00 MB
Load Address: 00100000
Entry Point: 00100000
$ file *.uimg
output.uimg: u-boot legacy uImage, , Linux/ARM, OS Kernel Image (Not \
compressed), 152 bytes, Mon Jul 8 16:04:11 2013, Load Address: 0x00100000,\
Entry Point: 0x00100000, Header CRC: 0x3C62F575, Data CRC: 0x69CE9647
将u-boot.bin和output.uimg打包为一个文件:
$ cat u-boot.bin output.uimg >flash.bin
下面这条命令用于计算output.img在使用u-boot加载完flash.bin后在内存中的地址,-kernel选项告诉qemu从0x100000开始加载镜像,即65536。
65536+u-boot.bin后的大小,即output.img在内存中的地址。printf则是用16进制的格式打印出来,以便加载.
$ printf "0x%X" $(expr $(stat -c%s u-boot.bin) + 65536)
0x2525C
启动qemu-system-arm并运行自定义镜像:
$ qemu-system-arm -M versatilepb -nographic -kernel flash.bin
# iminfo 0x2525c
## Checking Image at 0002525c ...
Legacy image found
Image Name:
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 152 Bytes = 0.1 kB
Load Address: 00100000
Entry Point: 00100000
Verifying Checksum ... OK
VersatilePB # bootm 0x2525c
## Booting kernel from Legacy Image at 0002525c ...
Image Name:
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 152 Bytes = 0.1 kB
Load Address: 00100000
Entry Point: 00100000
Loading Kernel Image ... OK
OK
Starting kernel ...
Hello Open World
u-boot可以支持的选项还有很多,包括使用NFS/TFTP启动等等,留待以后慢慢研究。
Jul 7, 2013
Technology安装完ArchLinux后,发现网卡无法从路由器通过dhcp得到地址,ArchLinux的dhcp客户端是dhcpcd,默认配置文件。路由器型号是TP-link WR340G v5, 2010年入手的。
手动调用dhcpcd时候发现LOG里有NAK消息爆出。
翻了下Arch的论坛,这个问题是由于dhcpcd的参数配置引发的,某些dhcpcd向路由器请求的参数无法得到而导致,个人觉得大约是WR340G版本够老,无法提供这些个参数。
##解决方案一:
编辑/etc/dhcpcd.conf, 注释掉classless_static_routes 和 interface_mtu即可:
# option classless_static_routes
# Respect the network MTU.
# option interface_mtu
而后我们可以用systemd在每次启动的时候自动调用dhcpcd绑定地址:
$ systemctl enable dhcpcd@enp0s25
$ systemctl start dhcpcd@enp0s25
##解决方案二:
安装dhclient:
$ pacman -S dhclient
$ dhclient enp0s25
这种方法需要每次手动输入,不过我们可以使用netctl包来自动管理网络接口信息:
$ cp /etc/netctl/examples/ethernet-dhcp /etc/netctl/ethernet-dhcp
由netctl.profile查到指定dhcp客户端的字段,而后在/etc/netctl/ethernet-dhcp文件中添加:
DHCPClient=dhclient
# !!! 别忘了修改dhcp侦听的设备地址:
# Interface=eth0
Interface=enp0s25
把ethernet-dhcp作为netctl的默认启动配置文件:
$ netctl enable ethernet-dhcp
立即开启netctl:
$ netctl start ethernet-dhcp
查看netctl服务运行情况,我的网络是桥接的,和依据上面步骤配出来的字段会有所不同
$ systemctl list-units -t service | grep netctl
netctl@bridge.service loaded active exited Example Bridge connection
如果切换了网络环境,例如如果在待机唤醒时处于另一网络中,则需要用下列命令重新配置网络:
$ netctl restart ethernet-dhcp
两种方法各有千秋,前者比较灵活,但是遇到复杂网络配置的时候可能会很棘手,譬如多网卡/桥接等模型时容易把人弄晕。后者配置选项很多,但一劳永逸。
Jul 7, 2013
Technology1. 安装Qemu
ArchLinux的仓库里包含有qemu已编译好的包:
$ pacman -Ss qemu
extra/qemu 1.4.2-2 [installed]
A generic and open source processor emulator which achieves a good \
emulation speed by using dynamic translation.
$ pacman -S qemu
会根据默认配置安装好几乎所有平台支持的Qemu.
或者你可以手动下载源码包进行编译:官方下载地址在http://wiki.qemu.org/Download
安装完qemu后运行qemu-system-i386, 如果弹出窗口,则说明qemu安装正确。
2. 创建新虚拟机磁盘镜像
创建虚拟机的第一步是创建一个新的磁盘镜像,qemu提供了对多种磁盘镜像格式的支持,如raw、qcow2、qed、vdi等,qemu-img的帮助里介绍qcow2是最多才多艺(Versatile)的格式,支持压缩、加密等功能,还能最大程度节省磁盘空间。我们选择它来做磁盘镜像(Virtualbox可以直接读取qcow2格式的虚拟机镜像)。
$ qemu-img create -f qcow2 ubuntu.qcow2 16G
Formatting 'ubuntu.qcow2', fmt=qcow2 size=17179869184 encryption=off \
cluster_size=65536 lazy_refcounts=off
3. 启动并安装虚拟机:
$ qemu-system-i386 -hda ubuntu.qcow2 -boot d -cdrom \
./ubuntu-13.04-desktop-i386.iso -m 1024 -enable-kvm
-boot d代表优先从光驱启动,对应的选项有a, b (软驱 1 和 2), c (硬盘优先), d (光盘优先), n-p(支持Etherboot的网卡1-4).
安装ubuntu的步骤很直观,这里就不用篇幅描述了。安装完毕后,使用下列命令启动安装好的虚拟机镜像
$ qemu-system-i386 -hda ubuntu.qcow2 -m 1024 -enable-kvm
4. 配置虚拟机网络:
4.1 使用桥接网络
这种方法需要改动系统配置,使用bridge-utils来创建虚拟网卡和实际网卡之间的桥接。
$ pacman -Ss bridge-utils
core/bridge-utils 1.5-2
Utilities for configuring the Linux ethernet bridge
$ pacman -S bridge-utils
创建桥接设备(br0)
$ modprobe bridge
$ brctl addbr br0
出现add bridge failed: Package not installed时的解决方法:
$ brctl addbr br0
add bridge failed: Package not installed
# 查看kernel中关于bridge配置选项
$ zcat /proc/config.gz | grep CONFIG_BRIDGE=
CONFIG_BRIDGE=m
# 查看是否存在ko文件
$ ls /usr/lib/modules/`uname -r`/kernel/net/bridge
bridge.ko.gz netfilter
# 加载bridge内核模块
$ modprobe bridge
# 检查内核模块是否被加载
$ lsmod | grep ^bridge
bridge 93187 0
若modprobe bridge后lsmod看不到bridge模块,有可能是因为更新完系统安装到新的kernel version后没有重启,ArchLinux是一个非常激进的发行版,内核往往几天一升级,习惯休眠或长期不关机的用户可能会碰到这个问题。
检查bridge网络
$ brctl show br0
bridge name bridge id STP enabled interfaces
br0 8000.000000000000 no
关于STP:
Spanning Tree Protocol (STP) is a Layer 2 protocol that runs on bridges and
switches. The specification for STP is IEEE 802.1D. The main purpose of STP is
to ensure that you do not create loops when you have redundant paths in your
network. Loops are deadly to a network.
生成树协议运行于bridge或交换机上,主要目的为确保在存在冗余路径时网络中不会生成回路,回路会造成网络的死循环。
用下列命令查看网口信息, 或者ifconfig -a直接查看也可:
$ ifconfig -s | awk '{print $1}' | grep -v "Iface\|lo"
enp0s25
将enp0s25加入到br0
$ /sbin/ifconfig enp0s25 down
$ /sbin/ifconfig enp0s25 0.0.0.0 promisc up
$ brctl addif br0 enp0s25
$ dhcpcd br0
查看bridge端口信息,发现enp0s25已经被加入了br0:
$ brctl show br0
bridge name bridge id STP enabled interfaces
br0 8000.c8cbb8b48913 no enp0s25
有关bridge网络的dhcp相关配置,可以参考ArchLinux网络配置问题。
创建qemu启动脚本:
$ vim /etc/qemu-ifup
#!/bin/sh
echo "Executing /etc/qemu-ifup"
echo "Bringing up $1 for bridged mode..."
sudo /usr/bin/ip link set $1 up promisc on
echo "Adding $1 to br0..."
sudo /usr/bin/brctl addif br0 $1
sleep 2
更改脚本权限:
$ chmod 750 /etc/qemu-ifup
$ chown -R root /etc/qemu-ifup
$ chgrp kvm /etc/qemu-ifup
创建qemu结束脚本
$ vim /etc/qemu-ifdown
#!/bin/sh
echo "Executing /etc/qemu-ifdown"
sudo /usr/bin/ip link set $1 down
sudo /usr/bin/brctl delif br0 $1
sudo /usr/bin/ip link delete dev $1
更改脚本权限:
$ chmod 750 /etc/qemu-ifdown
$ chown -R root /etc/qemu-ifdown
$ chgrp kvm /etc/qemu-ifdown
添加当前用户到kvm用户组并在visudo中开放对应命令的权限:
$ usermod -a -G kvm Trusty
$ visudo
Cmnd_Alias QEMU=/usr/bin/ip,/usr/bin/modprobe,/usr/bin/brctl
%kvm ALL=NOPASSWD: QEMU
建立run-qemu文件,并添加到系统路径中.
$ vim /bin/run-qemu
#!/bin/bash
USERID=`whoami`
precreationg=$(/usr/bin/ip tuntap list | /usr/bin/cut -d: -f1 | /usr/bin/sort)
sudo /usr/bin/ip tuntap add user $USERID mode tap
postcreation=$(/usr/bin/ip tuntap list | /usr/bin/cut -d: -f1 | /usr/bin/sort)
IFACE=$(comm -13 <(echo "$precreationg") <(echo "$postcreation"))
# This line creates a random mac address. The downside is the dhcp server will
assign a different ip each time
printf -v macaddr "52:54:%02x:%02x:%02x:%02x" $(( $RANDOM & 0xff)) $(( $RANDOM &
0xff )) $(( $RANDOM & 0xff)) $(( $RANDOM & 0xff ))
# Instead, uncomment and edit this line to set an static mac address. The
benefit is that the dhcp server will assign the same ip.
# macaddr='52:54:be:36:42:a9'
qemu-system-i386 -enable-kvm -net nic,macaddr=$macaddr -net tap,ifname="$IFACE"
$*
sudo ip link set dev $IFACE down &> /dev/null
sudo ip tuntap del $IFACE mode tap &> /dev/null
$ sudo chmod a+w /bin/run-qemu
使用下列命令来运行qemu
$ /bin/run-qemu -hda ./ubuntu.qcow2 -m 1024 -vga std
运行多个run-qemu实例后的网络信息如下:
$ ifconfig -s
Iface MTU RX-OK RX-ERR RX-DRP RX-OVR TX-OK TX-ERR TX-DRP TX-OVR Flg
br0 1500 70676 0 0 0 64334 0 0 0 BMRU
enp0s25 1500 103814 0 0 0 75661 0 0 0 BMPRU
lo 65536 983 0 0 0 983 0 0 0 LRU
tap0 1500 3 0 0 0 11 0 0 0 BMPRU
tap1 1500 3 0 0 0 11 0 0 0 BMPRU
4.2 使用VDE(Virtual Distrubuted Ethernet)创建Qemu网络,这种方法无需改变系统配置。
有关VDE的配置可以参考前面写过的在CentOS上安装基于Qemu的虚拟机一文。
值得注意的是, vdeswitch和slirpvde都可以在ArchLinux的软件库中找到:
$ pacman -Ss vde
extra/vde2 2.3.2-4 [installed]
Virtual Distributed Ethernet for emulators like qemu
使用VDE创建的网络对外是不可见的,它使用由slirpvde分配的dhcp地址,通常以10.0.0开头,VDE配置的网络也可以在VirtualBox中看到,VirtualBox中关于NAT的网络配置就是基于VDE的。
Jul 6, 2013
Technology在X86_64的ArchLinux上安装Mentor Graphics提供的arm交叉编译链时出现下列问题:
$ ./arm-2013.05-23-arm-none-eabi.bin
Checking for required programs: awk grep sed bzip2 gunzip
===============================================================
Error: Missing 32-bit libraries on 64-bit Linux host
===============================================================
Your 64-bit Linux host is missing the 32-bit libraries
required to install and use Sourcery CodeBench.
解决方法:
编辑/etc/pacman.conf,去掉下列两行的注释
[multilib]
Include = /etc/pacman.d/mirrorlist
而后安装必要的ia32相关的包:
$ pacman -Sy
$ pacman -S lib32-glibc
$ pacman -S lib32-gtk lib32-gtk2
安装好以后执行前面被中断的安装进程,这时候可以顺利安装了。
安装完毕后记得把交叉编译链的路径加入到系统路径中,最好在~/.bashrc里加上一笔:
export PATH=$HOME/CodeSourcery/Sourcery_CodeBench_Lite_for_ARM_EABI/bin:$PATH
export PATH=$HOME/CodeSourcery/Sourcery_CodeBench_Lite_for_ARM_GNU_Linux/bin:$PATH
ArchLinux的yaourt仓库里也有arm-none-eabi和arm-none-linux-eabi等交叉编译链,但是每次编译都会出现莫名其妙的错误,使用现成的编译链能大大节省开发时间。
Jul 5, 2013
Technology刚安装好的ArchLinux上只有基本的系统组件,启动以后连ifconfig都没有(其实ifconfig早在N年前就被干掉,以ip命令代替了)。在这种一穷二白的情况下,如何配置好网络参数?下面的步骤可以让人一劳永逸。
1. 查看网络接口信息:
$ ip link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT qlen 1000
link/ether 08:00:27:09:fd:b7 brd ff:ff:ff:ff:ff:ff
可以看到enp0s3为有线端口,未启动,无地址无网关无路由。
2. 启动网口:
$ ip link enp0s3 up
3. 配置网卡地址:
$ ip addr add 192.168.1.133/24 broadcast 192.168.1.255 dev enp0s3
参数解释:IP地址: 192.168.1.133, 广播地址:192.168.1.255
4. 配置默认路由为192.168.1.1:
$ ip default-gateway 192.168.1.1
5. 查看接口信息:
#路由信息
$ ip route show
#地址信息
$ ip addr show
6. 添加dns解析信息:
$ vim /etc/resolv.conf
输入ISP提供的dns服务器信息,例如:
nameserver 58.XXX.xx.xx
nameserver 221.x.x.xx
7. 安装net-tools,这里包含了ifconfig,终于可以不用忍受ip命令的折磨了。但是我记得看过一个高手的文章,他建议使用ip而不是使用陈旧的功能有限的ifconfig,高手开了个玩笑:“记住每次你敲ifconfig时,就会有一只无辜的小猫咪因为偷吃奶酪被击杀,可怜可怜小猫咪吧 :(”。虽然ifconfig很方便也是大多数教程里的常用配置,还是建议大家尽快适应繁琐的ip命令。
$ pacman -S net-tools
8. 安装dhcpcd并加入到系统启动项中:
$ pacman -S dhcpcd
# 临时启动dhcpcd
$ systemctl start dhcpcd@enp0s3
# 将dhcpcd加入到启动项中
$ systemctl enable dhcpcd@enp0s3
现在重启机器,就可以从dhcp服务器自动获取地址并配置dns服务器等信息了。
9. 其他:
删除当前已经绑定的IP地址:
$ ip addr del 192.168.1.134/32 dev enp0s3
若机器处于有防火墙的机器中,则需要配置好proxy信息才能正常使用网络,在命令行下,输入一下命令:
$ export http_proxy=http://ip_address:ip_port
$ export https_proxy=http://ip_address:ip_port
$ export ftp_proxy=http://ip_address:ip_port
$ export ftps_proxy=http://ip_address:ip_port