2017-01-11 14:50:56 cc214042 阅读数 0
  • 杂项

    了解ARM体系结体和指令系统 使用ARM汇编编写程序

    18618课时 0分钟 4人学习 张先凤
    免费试看

第六部分:Linux应用编程篇

6.1.2 Linux应用编程需要学习什么

C语言和数据结构作为基础,重点学习链表。
学习的内容:
1)库函数的熟悉,比如 memcpy,memset,strstr,strcpy 等等
2)SHELL编程,现在很多游戏行业,必须熟悉 SHELL 编程
3)文件IO编程, 这个不用解释,哪都能用着
4)进程编程,比如进程间通信,也是到处可见
5)多线程编程,试想如果你的windows操作系统没有多线程,会是什么样的呢
6)网络编程, 网络公司一定要求你熟悉网络编程,想进腾讯就好好学这个吧
参考书籍《Linux程序设计第四版》和《UNIX高级环境编程》

6.2 文件IO编程

文件分为:普通文件、目录文件、链接文件和设备文件。
Linux环境下,所有设备和文件的操作都使用文件描述符来进行的。
不带缓存的文件IO程序设计是Linux文件操作程序设计的重点。(不能移植到非POSIX标准的系统)
文件底层 I/O 操作的系统调用主要用到 5 个函数: open()、 close()、 read()、 write()、 lseek()。

问题:
Linux下编程的执行顺序是怎么样的?
进程与线程的具体表现形式?
信号量的PV原语?

6.3 进程控制编程

进程标志:PID(子进程),PPID(父进程)
进程状态:执行态,就绪态,阻塞态
fork()函数创建进程,返回子进程的进程号
vfork()函数,不产生父进程的副本,“写操作时拷贝”技术(copy-on-write)
exec()函数族可以根据文件名或目录找到可执行文件,并用来取代原调用进程的数据段、代码段和堆栈段。
函数族列表

waitpid函数,使父进程阻塞,直到子进程结束退出或者子进程接到了一个指定的信号为止。

6.4 进程间通信

进程数据共享时进行。
进程间的通讯方式:管道,消息队列,共享内存,信号量,套接字。

管道:作用是把一个程序的输出直接连接到另一个程序的输入。
无名管道的特点:
1)只能用于具有亲缘关系的进程之间的通信,例如父子或者兄弟进程
2)半双工的通信模式,固定的读端口和写端口
3)可以看做是特殊的文件,只存在于内存中(带有p的文件就是管道文件)

pipe()函数,创建无名管道,fd[0]固定用于管道读端,fd[1]固定用于管道写端
close()函数,关闭管道,分别关闭各个文件描述符

有名管道可以使互不相关的两个进程实现彼此通信,有名管道又称FIFO(first In first Out),即先进先出
mkfifo()函数,创建有名管道

6.4.3共享内存
内核留出一块内存,可以由需要访问的进程将其映射到自己的私有地址空间,不同进程可以及时的看到某进程对共享内存的数据进行更新。
需要引进某种同步机制,如互斥锁和信号量。
共享内存分为两个步骤,一创建共享内存,shmget()函数,也就是从内存中获得一段共享内存区域。二映射共享内存,也就是把这段刚创建的共享内存映射到具体的进程空间去,shmat()函数。撤销映射,shmdt()函数。
ipcs命令:报告进程间通信机制状态,用于查看共享内存,消息队列等各种进程间通信机制的情况。

消息队列,由“队列ID”来标识

6.5 线程编程

当进程在进行切换操作时都需要进行上下文切换,从而造成很大的花销。为了减少处理机的空间时间,支持多处理器和减少上下文切换的开销,这样一来,线程就诞生了。
进程是系统中程序执行和资源分配的基本单位。相应地,线程是一个进程内的基本调度单位,也可以称为轻量级进程。
多线程系统中,线程和进程的关系:

pthread_create()函数:创建线程
pthread_exit()函数:退出线程
exit()函数:退出进程,进程结束后,进程中的所有进程都会因为进程的结束而结束
pthread_join()函数:挂起当前线程

线程的属性包括:绑定属性、分离属性、堆栈地址、堆栈大小、优先级。
其中系统默认的属性为非绑定、非分离、缺省1M大小的堆栈,与父进程同样级别的优先级。

属性设置的步骤:
初始化函数:pthread_attr_init()
设置绑定属性:pthread_attr_setscope()
设置分离属性:pthread_attr_setdetachstate()
设置优先级:pthread_attr_getscheparam()和pthread_attr_setchedparam()
创建线程:pthread_create()

资源的访问存在唯一性,简单的说,就是对资源的访问,每次只能有一个进程,这时就需要引入同步和互斥机制。在POSIX中线程同步的方法,主要有互斥锁(mutex)和信号量。
互斥锁的操作主要包括以下几个步骤: 
1.互斥锁初始化:pthread_mutex_init 
2.互斥锁上锁:pthread_mutex_lock 
3.互斥锁判断上锁:pthread_mutex_trylock 
4.互斥锁解锁:pthread_mutex_unlock 
5.消除互斥锁:pthread_mutex_destroy

信号量其实就是一个非负的整数计数器,是操作系统中所用的PV原语,它主要应用于进程或线程间的同步与互斥。

6.6 网络编程

TCP/IP协议包含了上百个功能的协议,如ICMP(互联网控制信息协议)、FTP(文件传输协议)、UDP(用户数据报协议)、ARP(地址解析协议)等。TCP负责发现传输的问题,一旦有问题就会发出重传的信号,直到所有数据安全正确地传输到目的地。而IP就是给因特网的每一台电脑规定一个地址。

IP地址,端口,域名

套接字(socket),在网络中用来描述计算机中不同程序与其他计算机程序的通信方式。
套接字类型:流式socket(TCP)、数据报socket(UDP)和原始socket(IP或ICMP)。
套接字(也叫套接口)由三个参数构成:IP地址,端口号和传输层协议。
常用的数据结构sockaddr和sockaddr_in,一般使用sockaddr_in这种形式。
sa_family(地址族)常见值如下:
AF_INET:IPv4 协议 
AF_INET6:IPv6 协议 
AF_LOCAL:UNIX域协议

主机名与IP地址间的转换
数据存储大小端的问题

6.6.2 网络基础编程
主要介绍TCP和UDP协议
TCP
TCP管理到其他socket的数据传递,可以说,通过IP源/目的可以唯一的区分网络中两个设备的关联,区分网络中两个应用程序的关联。TCP三次握手的过程:
1)初始化主机通过一个同步标志置位的数据段发出会话请求;
2)接收主机通过发回具有以下项目的数据段表示回复:同步标志置位、即将发生的数据段的起始字节的顺序号、应答并带有将受到的下一个数据段的字节顺序号。
3)请求主机再回送一个数据段,并带有确认顺序号和确认号。
TCP协议编程相关函数:
socket(), bind(), connect(), listen(), accept(), close(), send(), recv()。

UDP
UDP 即用户数据报协议,它是一种无连接协议,因此不需要像 TCP 那样通过三次握手来建立一个连接。
UDP协议编程相关函数:
bind(), close(), sendto(), recvfrom()。
2013-04-27 09:29:43 wyc09 阅读数 542
  • 杂项

    了解ARM体系结体和指令系统 使用ARM汇编编写程序

    18618课时 0分钟 4人学习 张先凤
    免费试看

ARM Linux特指运行于ARM架构处理器平台的Linux,区别于运行于PC上的X86 Linux。

ARM架构处理器多用在嵌入式系统中,通常被集成到片上系统(SoC)。由于片上系统整合外部设备控制器的多样性,对于任何一片特定的片上系统,需要对ARM Linux进行定制,以使集成在片上系统中的各项功能可用,这个过程称为ARM Linux移植。

ARM Linux移植的主要工作:1)Bootloader移植;2)ARM Linux内核移植;3)根文件系统制作。完成这三项基本工作之后,就可以在运行于片上系统之上的ARM Linux基础上开发针对特定需求的应用,包括推迟到开发阶段的驱动程序、应用程序等。 

1)Bootloader移植。

ARM Linux内核被设计为尽可能平台无关,而Bootloader则负责提供板级支持包(BSP)的功能,在为ARM Linux内核提供基本的运行环境之后,如CPU可用、内存可用,便可加载ARM Linux内核,并将系统控制权完全交给ARM Linux内核。这个过程称为引导ARM Linux内核。一般来讲,Bootloader是特定于硬件平台的,但是由于某些开源Bootloader,如UBOOT的存在,使得开发人员可以对既有Bootloader进行尽可能少量的修改,便可将其用来在特定目标板上引导ARM Linux内核。

UBOOT引导ARM Linux内核的一般流程:初始化CPU环境,如关中断、设定运行模式 --> 初始化DRAM控制器,以使内存可用 --> 如有必要,初始化串口用于输出引导信息,初始化网口用于下载ARM Linux内核镜像 --> 加载ARM Linux内核镜像 --> 为ARM Linux内核准备参数,将控制流转到ARM Linux内核入口。

2)ARM Linux内核移植。

ARM Linux内核接受Bootloader的引导参数,如DRAM大小和起始地址、用作Console的设备的名称、根文件系统的位置。为了使ARM Linux内核能够正常使用片上系统芯片内部及目标板上的各种功能,在这个过程中需要在ARM Linux内核代码中加入平台特定的一些代码,通常将这些代码存放在arch/arm目录下的某个机器特定的目录中。ARM Linux内核中已经包含了大量平台特定的代码,但相比平台的多样性,这些代码还是不够的。 在编译生成ARM Linux内核镜像之前,需要对ARM Linux内核进行必要的配置,使在内核代码中实现的某项功能被加入或不加入ARM Linux内核,如加入对mini2440目标板和smdk2440目标板的支持、加入针对三星SoC串口的驱动、不加入FAT文件系统。需要说明一下,ARM Linux内核可以同时支持多种目标板(或称机器类型),但在启动的时候只会根据Bootloader在R1寄存器中指定的机器码来选定一款支持的机器类型,在执行平台无关代码之前进行与选定机器类型平台相关的初始化工作。在平台相关的初始化工作中可以将目标板上的各种功能都初始化,也可什么都不做,而将这些工作推迟到开发阶段来完成。

3)根文件系统制作。

如果ARM Linux内核启动后不需要访问文件系统,就不需要做这项工作。但是大多数情况下,ARM Linux内核在启动后会从文件系统中读取配置文件,并根据配置文件中的内容完成更多的工作,如启动必要的工作进程,使系统进入到指定的工作状态。在ARM Linux内核的启动参数中,initrd指定ARM Linux内核启动后需要执行的程序,ARM Linux内核从指定的根文件系统中加载这个程序并用其创建init进程。init进程做什么工作则是由这个指定的程序来决定的。可能的工作,如启动一个Shell程序或者打开一个图形用户界面。BusyBox提供了一个用于此目的的程序,名称为linuxrc,可以将linuxrc配置为启动一个类似于Linux中的bash的Shell程序,BusyBox同样提供了这个Shell程序。

2018-03-19 00:25:25 skyleemon 阅读数 3895
  • 杂项

    了解ARM体系结体和指令系统 使用ARM汇编编写程序

    18618课时 0分钟 4人学习 张先凤
    免费试看

先搭建必要的开发工具和下载源码

https://blog.csdn.net/skyleemon/article/details/78360241

内核编译,使用的内核版本分支如下:

guang@guang-kylin:~/Develop/linux-stable$ git branch
* master

1 修改顶层目录下的makefile:

guang@guang-kylin:~/Develop/linux-stable$ vi Makefile

ARCH ?= $(SUBARCH)

CROSS_COMPILE ?= $(CONFIG_CROSS_COMPILE:”%”=%)
修改为:
ARCH ?= arm
CROSS_COMPILE ?= arm-linux-gnueabi-

2 配置对应的开发板,这里用的是vexpress-a9,如下:

make vexpress_defconfig

3 编译zImage,module以及dtb:

make zImage
make modules
make dtbs
zImage生成路径:
arch/arm/boot/zImage
modules生成路径:
drivers/video/backlight/*.ko
dtbs生成路径:
arch/arm/boot/dts/vexpress-v2p-ca9.dtb

4 qemu启动内核,看看效果,由于还未挂载根文件系统,所以VFS会有报错

guang@guang-kylin:~/Develop/linux-stable$ qemu-system-arm -M vexpress-a9 -m 512M -kernel arch/arm/boot/zImage -dtb arch/arm/boot/dts/vexpress-v2p-ca9.dtb -nographic -append “console=ttyAMA0”
/****************************************************************/
pulseaudio: set_sink_input_volume() failed
pulseaudio: Reason: Invalid argument
pulseaudio: set_sink_input_mute() failed
pulseaudio: Reason: Invalid argument
Booting Linux on physical CPU 0x0
Linux version 4.17.0+ (guang@guang-kylin) (gcc version 7.3.0 (Ubuntu/Linaro 7.3.0-16ubuntu3)) #1 SMP Mon Jun 11 05:05:41 CST 2018
……// 省略了很多打印信息
VFS: Cannot open root device “(null)” or unknown-block(0,0): error -6
Please append a correct “root=” boot option; here are the available partitions:
1f00 131072 mtdblock0
(driver?)
1f01 32768 mtdblock1
(driver?)
Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)
CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.17.0+ #1
Hardware name: ARM-Versatile Express
[<8011074c>] (unwind_backtrace) from [<8010cd4c>] (show_stack+0x10/0x14)
[<8010cd4c>] (show_stack) from [<80694dd4>] (dump_stack+0x88/0x9c)
[<80694dd4>] (dump_stack) from [<8011ff6c>] (panic+0xf0/0x25c)
[<8011ff6c>] (panic) from [<80901588>] (mount_block_root+0x1ec/0x2d8)
[<80901588>] (mount_block_root) from [<809017b8>] (mount_root+0x144/0x160)
[<809017b8>] (mount_root) from [<80901924>] (prepare_namespace+0x150/0x198)
[<80901924>] (prepare_namespace) from [<80901174>] (kernel_init_freeable+0x340/0x350)
[<80901174>] (kernel_init_freeable) from [<806a91f8>] (kernel_init+0x8/0x114)
[<806a91f8>] (kernel_init) from [<801010e8>] (ret_from_fork+0x14/0x2c)
Exception stack(0x9f48ffb0 to 0x9f48fff8)
ffa0: 00000000 00000000 00000000 00000000
ffc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
ffe0: 00000000 00000000 00000000 00000000 00000013 00000000
—[ end Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0) ]—

用kill杀死对应的qemu-system-arm进程,咱们开始制作根文件系统

/****************************************************************/

5 busybox制作根文件系统

5.1 修改Makefile,新的busybox的makefile下面的选项是空配置的,需要修改如下:

CROSS_COMPILE ?= arm-linux-gnueabi-
ARCH ?= arm

5.2 配置

make defconfig或者make menuconfig
如果是menuconfig,下图选*:
Settings —>
— Build Options
[ ] Build static binary (no shared libs)
这里写图片描述
这里写图片描述
这里写图片描述

可以看到生成的.config文件

guang@guang-kylin:~/Develop/busybox$ ls -al .config
-rw-rw-r– 1 guang guang 27083 6月 11 12:34 .config

参考文档:

https://blog.csdn.net/qq_36788698/article/details/76647347
https://www.cnblogs.com/PengfeiSong/p/6443149.html
https://unix.stackexchange.com/questions/120198/how-to-fix-boot-into-initramfs-prompt-and-mount-cant-read-etc-fstab-no-su

5.3 编译 && 安装

make
make install

如下提示安装成功

*————————————————–
You will probably need to make your busybox binary
setuid root to ensure all configured applets will
work properly.
*————————————————–

生成的的_install文件如下,包含了各种shell命令:

guang@guang-kylin:~/Develop/busybox$ ls -al ./_install/

total 20
drwxrwxr-x 5 guang guang 4096 6月 11 12:49 .
drwxrwxr-x 38 guang guang 4096 6月 11 12:48 ..
drwxrwxr-x 2 guang guang 4096 6月 11 12:49 bin
lrwxrwxrwx 1 root root 11 6月 11 12:49 linuxrc -> bin/busybox
drwxrwxr-x 2 guang guang 4096 6月 11 12:49 sbin
drwxrwxr-x 4 guang guang 4096 6月 11 12:48 usr

5.4 制作根文件系统
5.4.1 新建根目录

guang@guang-kylin:~/Develop$ mkdir trainning

guang@guang-kylin:~/Develop$ cd trainning/

guang@guang-kylin:~/Develop/trainning$ mkdir rootfs

guang@guang-kylin:~/Develop/trainning$ cd rootfs/

5.4.2 新建库文件目录,完成库文件的拷贝

guang@guang-kylin:~/Develop/trainning/rootfs$ mkdir lib

guang@guang-kylin:~/Develop/trainning/rootfs$ ls
lib

guang@guang-kylin:~/Develop/trainning/rootfs$ cp -r ../../busybox/_install/* ./

guang@guang-kylin:~/Develop/trainning/rootfs$ ls
bin lib linuxrc sbin usr

文件系统运行在arm平台,因此还需要arm-linux-gnueabi的库

guang@guang-kylin:~/Develop/trainning/rootfs$ cp -p /usr/arm-linux-gnueabi/lib/* ./lib
这里写图片描述

5.4.3 创建设备文件

guang@guang-kylin:~/Develop/trainning/rootfs$ mkdir dev

guang@guang-kylin:~/Develop/trainning/rootfs$ ls
bin dev lib linuxrc sbin usr

创建4个串口设备

guang@guang-kylin:~/Develop/trainning/rootfs/dev$ sudo mknod -m 666 tty1 c 4 1

[sudo] password for guang:
guang@guang-kylin:~/Develop/trainning/rootfs/dev$ sudo mknod -m 666 tty2 c 4 2

guang@guang-kylin:~/Develop/trainning/rootfs/dev$ sudo mknod -m 666 tty3 c 4 3

guang@guang-kylin:~/Develop/trainning/rootfs/dev$ sudo mknod -m 666 tty4 c 4 4

创建控制台

guang@guang-kylin:~/Develop/trainning/rootfs/dev$ sudo mknod -m 666 console c 5 1

创建null

guang@guang-kylin:~/Develop/trainning/rootfs/dev$ sudo mknod -m 666 null c 1 3
这里写图片描述

5.4.3 制作SD根文件系统镜像
生成虚拟sd卡并格式化为ext格式:

dd if=/dev/zero of=rootfs.ext3 bs=1M count=32
mkfs.ext3 rootfs.ext3
这里写图片描述

将虚拟sd卡挂载到/mnt,拷贝rootfs的所有文件到sd,卸载sd(块设备不能直接读写)

mount -t ext3 rootfs.ext3 /mnt/ -o loop
cp -r rootfs/* /mnt
umount /mnt
这里写图片描述

5.4.4 启动内核,挂载rootfs

guang@guang-kylin:~/Develop/trainning$ qemu-system-arm -M vexpress-a9 -m 512M -dtb ../linux-stable/arch/arm/boot/dts/vexpress-v2p-ca9.dtb -kernel ../linux-stable/arch/arm/boot/zImage -nographic -append “root=/dev/mmcblk0 rw console=ttyAMA0” -sd rootfs.ext3

不带lcd的启动效果:

这里写图片描述

带lcd的启动效果:

qemu-system-arm -M vexpress-a9 -m 512M -dtb ../linux-stable/arch/arm/boot/dts/vexpress-v2p-ca9.dtb -kernel ../linux-stable/arch/arm/boot/zImage -append “root=/dev/mmcblk0 rw console=tty0” -sd rootfs.ext3
这里写图片描述

5.4.5 一个简单的ko测试程序

这里写图片描述

报错解决:写一个makefile,自动包含头文件路径

这里写图片描述

// qemu.c:
#include <linux/init.h>
#include <linux/module.h>

static int __init qemu_init (void)
{
    printk (KERN_INFO"[Info]Hello! Enter QEMU.");
    return 0;
}
module_init (qemu_init);

static void __exit qemu_exit (void)
{
    printk (KERN_INFO"[Info]Hello! Exit QEMU.");
}
module_exit (qemu_exit);

MODULE_AUTHOR ("Guang-kylin");
MODULE_LICENSE ("GPL v2");
MODULE_DESCRIPTION ("A simple qume test module");
MODULE_ALIAS ("QEMU module");
// Makefile
KVERS = $(shell uname -r)

# Kernel modules
obj-m += qemu.o

#EXTRA_CFLAGS=-g -O0

build: kernel_modules

kernel_modules:
        make -C /lib/modules/$(KVERS)/build M=$(CURDIR) modules

clean:
        make -C /lib/modules/$(KVERS)/build M=$(CURDIR) clean
rootfs根文件系统下面创建一个test目录用来存放ko文件
拷贝rootfs的内容到rootfs.ext3虚拟SD中

mount -t ext3 rootfs.ext3 /mnt/ -o loop
cp -r rootfs/* /mnt
umount /mnt

启动开发板,加载KO,报错

这里写图片描述

检查一下ko的类型,发现是x86的ko,Makefile还得再修改一下,ko必须是arm-linux-gnueabi交叉编译器生成的,和生成zImage的编译器版本一致

这里写图片描述

修改过后的Makefile:
KDIR=/home/guang/Develop/linux-stable #linux代码路径,没有详细研究依赖了那些文件,全部包含了
PWD=$(shell pwd)

# Kernel modules
obj-m += qemu.o
module-objs = qemu.o

ARCH=arm
CROSS_COMPILE=arm-linux-gnueabi-

CC := $(CROSS_COMPILE)gcc
LD := $(CROSS_COMPILE)ld

#EXTRA_CFLAGS=-g -O0

default:
    make -C $(KDIR) M=$(PWD) modules
clean:
    rm -f *.ko *.o *.mod.c *.symvers *.order
查看ko,拷贝rootfs的内容到rootfs.ext3,查看加载效果

这里写图片描述

把zImage和dtb文件都拷贝到同一个目录了,在当前目录敲命令行省事,也可以写成一个shell脚本,后面再搞

这里写图片描述
/*****/
qemu-system-arm -M vexpress-a9 -m 512M -dtb ./vexpress-v2p-ca9.dtb -kernel ./zImage -nographic -append “root=/dev/mmcblk0 rw console=ttyAMA0” -sd rootfs.ext3
/*****/

加载还是报错,rcS找不到,文件系统还没有制作完成,还得继续

这里写图片描述

5.4.6 创建etc,进一步完善根文件系统

guang@guang-ubuntu:~/Develop/trainning/rootfs$ mkdir etc

guang@guang-ubuntu:~/Develop/trainning/rootfs$ cd etc

创建inittab
::sysinit:/etc/init.d/rcS
#::respawn:-/bin/sh
#tty2::askfirst:-/bin/sh
#::ctrlaltdel:/bin/umount -a -r

console::askfirst:-/bin/sh
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r
创建fstab
proc            /proc           proc    defaults                0       0
tmpfs           /tmp            tmpfs   defaults                0       0
sysfs           /sys            sysfs   defaults                0       0
tmpfs           /dev            tmpfs   defaults                0       0
var             /dev            tmpfs   defaults                0       0
ramfs           /dev            ramfs   defaults                0       0
创建profile
PS1='guang@arm-vexpress:\w # ' 
export PS1
创建init.d/rcS
#! /bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin
LD_LIBRARY_PATH=/lib
export PATH LD_LIBRARY_PATH

mount -a
mkdir -p /dev/pts
mount -t devpts devpts /dev/pts
mdev -s
mkdir -p /var/lock

echo "-----------------------------------"

echo " welcome to A9 vexpress board"

echo "-----------------------------------"
5.4.7 用最新的rootfs覆盖rootfs.ext3虚拟SD卡,启动开发板验证,效果如下,还有问题,待调试:

这里写图片描述

以上问题换了linux kernel得到解决,疑是内核污染的问题,版本4.17.0+

6 使用u-boot加载linux kernel

6.1 修改顶层Makefile,指定交叉编译器

CROSS_COMPILE ?= arm-linux-gnueabi-

6.2 修改顶层config.mk,指定ARM架构

ARCH := arm

6.3 配置开发板

make vexpress_ca9x4_defconfig

6.4 编译u-boot

make –j4

6.5 运行u-boot

qemu-system-arm -M vexpress-a9 -kernel u-boot -nographic -m 512M

6.5 配置QEMU的网络功能

采用桥接(bridge)的网络连接与Host通信
需要主机内核tun/tap模块支持(linux17.04以后的版本都支持了,不支持的老版本需要自己创建,我安装的ubuntu是18.04,故已经有了这个模块)
这里写图片描述

6.5.1 主机安装工具包:

apt install uml-utilities bridge-utils

6.5.2 创建tun设备文件:/dev/net/tun(如果没有)
6.5.3 修改/etc/network/interfaces文件,文件最后添加如下内容并保存,enp0s3字段是ifconfig查到的虚拟网卡的名称

auto enp0s3
auto br0
iface br0 inet dhcp
bridge_ports enp0s3

6.5.4 reboot,如下br0已经生成, ip是10.0.2.15:
guang@guang-ubuntu:~$ ifconfig
br0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.0.2.15  netmask 255.255.255.0  broadcast 10.0.2.255
        inet6 fe80::a00:27ff:fe6e:98c6  prefixlen 64  scopeid 0x20<link>
        ether 08:00:27:6e:98:c6  txqueuelen 1000  (Ethernet)
        RX packets 156  bytes 346295 (346.2 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 229  bytes 27996 (27.9 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

enp0s3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        ether 08:00:27:6e:98:c6  txqueuelen 1000  (Ethernet)
        RX packets 374  bytes 360251 (360.2 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 229  bytes 28436 (28.4 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 62  bytes 5127 (5.1 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 62  bytes 5127 (5.1 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

guang@guang-ubuntu:~$ 
6.5.5 编译uImage

make LOADADDR=0x60003000 uImage -j4

6.5.6 主机TFTP工具安装

apt-get install tftp-hpa tftpd-hpa xinetd

6.5.7 修改配置文件:/etc/default/tftpd-hpa
# /etc/default/tftpd-hpa

TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/home/guang/Develop/trainning/tftpboot"
TFTP_ADDRESS="0.0.0.0:69"
# TFTP_OPTIONS="--secure"
TFTP_OPTIONS="-l -c -s"                     
6.5.8 创建tftpboot目录
guang@guang-ubuntu:~/Develop/trainning$ mkdir tftpboot
guang@guang-ubuntu:~/Develop/trainning$ chmod +rwx tftpboot
guang@guang-ubuntu:~/Develop/trainning$ cd tftpboot/
guang@guang-ubuntu:~/Develop/trainning/tftpboot$ pwd
/home/guang/Develop/trainning/tftpboot
6.5.8 重启tftp服务
guang@guang-ubuntu:~/Develop/trainning$ sudo /etc/init.d/tftpd-hpa restart
[ ok ] Restarting tftpd-hpa (via systemctl): tftpd-hpa.service.
6.5.8 修改u-boot文件:include/configs/vexpress_common.h
/*config qemu' network<Add by guang 20180618>*/                                                                                                                                 
#define CONFIG_BOOTCOMMAND \
        "tftp 0x60003000 uImage;tftp 0x60500000 vexpress-v2p-ca9.dtb; \
        setenv bootargs 'root=/dev/mmcblk0 console=tty0'; \
        bootm 0x60003000 - 0x60500000;"

#define CONFIG_IPADDR 10.0.2.14
#define CONFIG_NETMASK 255.255.255.0
#define CONFIG_SERVERIP 10.0.2.15
6.5.9 编译u-boot
6.5.8 创建tftpboot目录
2016-10-14 14:29:09 wh_19931117 阅读数 308
  • 杂项

    了解ARM体系结体和指令系统 使用ARM汇编编写程序

    18618课时 0分钟 4人学习 张先凤
    免费试看

Linux环境下ARM裸机开发工程的建立示例(Cortex-A8)

     本文将介绍如何在Linux环境下建立一个ARM的裸机开发项目工程,其内容将涉及Linux c语言,ARM汇编语言,Linux shell命令与及Linux工程管理器make的配置文件--Makefile的编写!

1.交叉编译工具的安装与配置


    (网上的教程已经很多,在此只给出工具的下载地址,安装与配置不作详述)
    工具下载地址(百度云盘)https://pan.baidu.com/s/1i4Im5k5

2.创建工程


在主目录(用户目录)下打开终端,创建工程文件夹:
[wh@localhost ~]$ mkdir pro
进入工程目录:
[wh@localhost ~]$ cd pro
创建工程文件,其中startup.S(S为大写)为裸机的启动程序,Makefile为Linux工程管理器make的配置文件,用于配置编译选项。
[wh@localhost pro]$ touch startup.S Makefile
文件:startup.S文件内容如下:
.text
.global _start
_start:

loop:
bl loop

.end
文件:Makefile文件内容如下:
CC = arm-linux-gcc
LD = arm-linux-ld
OBJCOPY = arm-linux-objcopy

startup.bin:startup.o
	$(LD) startup.o -o start.elf -Ttext=0x40000000
	$(OBJCOPY) -O binary -S start.elf $@
        
startup.o:startup.S
	(CC) $^ -o $@ -c
clean:
	$(RM)  ./*.o ./start.elf ./startup.bin -rf
.PHONY: clean

3.编译

    用终端进入工程目录,运行make命令即可编译,编译生成的startup.bin为可烧写至nand中的二进制程序。
    至此,一个裸机开发工程完成。
2017-09-09 14:49:46 qq_35144795 阅读数 207
  • 杂项

    了解ARM体系结体和指令系统 使用ARM汇编编写程序

    18618课时 0分钟 4人学习 张先凤
    免费试看

arm-linux的开发方式主要有四个:

方法一、

1、安装linux虚拟机

2、安装交叉编译器

3、安装tftp,进行相应配置

4、sd卡中使用superboot下载对应的u-boot,然后开发板切换到nand启动

5、在开发板中配置tftp,然后就可以下载linux中裸机程序bin文件

方法二、

直接使用sd卡中superboot下载bin文件

不过此方法我用于下载改写后的韦东山老师提供的6410裸机程序出现很多问题

方法三、

使用RVDS下载bin文件,前提也是要是用sd卡superboot下载相应u-boot,然后切换到nand启动,把j_link接上,在RVDS中启动调试,当然RVDS需要设置一下(百度一下会有相应教程)

方法四、

参数友善之臂论坛推出的2014年 裸机教程,需要miniTools


配了这么多天,方法二是 最简单的,不容易出现问题,但是也比较麻烦,每次都要取下SD卡来回切换。方法三需要openjtag,我没有,所以没用,不过看韦东山老师用的挺顺的,方法四我是领教了,配了很久都没弄好,在win10上装不上usb slave的驱动,没有数字签名,强制数字签名也关不了,要关的话得每次开机设置特麻烦,linux下配了半天总算是把secbulk配好了,也链接上了,但是下载失败。。。决定换方法一,在此记录下,既是总结也是方便以后查看。