利用 QEMU 模拟嵌入式系统制作全过程

这篇文章,将介绍如何用 QEMU 来搭建一个基于 ARM 的嵌入式 Linux 系统。通过该文章,你可以学习到如何配置 Kernel,如何交叉编译 Kernel,如何配置 busybox 并编译,如何制作 initramfs,如何制作根文件系统,如何定制自己的 uboot,如何通过 uboot 向 kernel 传递参数等。开始干活!

环境搭建

在实现我们的目标之前,我们需要搭建自己的工作环境。在这里,假设你的主机上已经有 gcc 本地编译环境,并运行 Ubuntu 12.10。但是这并不影响在其他的 linux 平台上进行,只要修改一下对应的命令就可以了。

阅读全文

11.8-const

const 关键字用来修饰一个对象,使其成为一个只读对象。比如:

1
const int n=10;

但是 const 所修饰的对象并不等于一个常量表达式。const 修饰的对象是一个运行时对象,而一个常量表达式是一个编译时对象。所以这也可以用来解释为什么用 const 修饰的整数来初始化一个数组是不行的。比如:

1
int a[n]; //error

阅读全文

10.20-宏

在 C 语言中。宏分为两种:对象式宏和函数式宏。

对象式宏就是不带参数的宏,只是进行一些简单的替换。而函数式宏是带函数的宏,外表看上去就像是一个函数。
比如:

1
2
#define TEST "this is a test"
#define PRINT(int) printf("PRINT: %d", int)

阅读全文

3.16-左值和右值

在 C 和 C++ 中,我们经常会碰到两个概念,lvalue 和 rvalue。甚至在编译程序的时候,也会碰到一些关于 lvalue 和 rvalue 的错误。

在 ISO IEC 的标准文档中,对这两个概念并没有详细说明,特别是 rvalue,只在一个地方提了一下。
在 IBM 的 XL C/C++ V8.0 for AIX 的标准文档中是这样来规定 lvalue:

An object is a region of storage that can be examined and stored into. An lvalue is an expression that refers to such an object.

阅读全文

1.25-隐式函数声明

在 C 语言中,隐式函数声明是指函数在调用之前没有明确的声明或定义。
不同的编译器对待隐式函数声明的方式不同。在 GCC 中,编译器只会给出一个警告,但是只要不和默认函数原型冲突,编译器是不会报错的。
下面来看一个实验:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// file test.c
#include <stdio.h>

int f1()
{
return f2();
}

int f2(int i)
{
return 1;
}

int main(int argc, char * argv[])
{
printf("%d\n",f1());
return 0;
}

阅读全文