1. 检验交叉编译器安装成功与否?
arm-linux-gcc -v
2. go to the kernel source dir
cd /source/linux-2.6.13
3. edit Makefile (set ARCH=arm set CROSS_COMPILE=arm-linux-)
make config[menuconfig] (第一次用先不要改选项)
make dep
make zImage
(then zImage is generated in arch/arm/boot/)
4.power up the hardware platform
in u-boot promt>>
printenv
注意四个环境变量...
setenv ipaddr xx.xx.xx.xx
saveenv
5. copy zImage into tftpboot dir
cp arch/arm/boot/zImage /tftpboot
6. check tftp server
cd /etc/xinetd.d
cat tftp
7. connect board with PC by LAN cable
8. power up the board
in u-boot shell
tftp 30008000 zImage
9. setenv bootargs console=ttySAC0,115200 root=/dev/nfs
nfsroot=192.168.1.xx:/source/rootfs
ip=192.168.1.xxx
saveenv
10 check nfs server
cat /etc/exports
11. go 30008000
12. make menuconfig
boot options->
13. disassemble hello.elf
arm-linux-objdump -d hello.elf > a.msg
vi a.msg
check swi
14. cd linux-2.6.13
vi *.map
arm-linux-objdump -d vmlinux > a.msg
15. compile app
arm-linux-gcc hello.c -o hello.elf
arm-linux-gcc hello.c -static -o hello.elf
16. (strip elf file to binary)
arm-linux-objcopy -O binary vmlinux vmlinux.bin
第二天课程:linux-2.4内核移植
clone a new board support in linux 2.4.18 derived from smdk2410
1. get needed file from ftp server
cd /root/
mkdir hwang
cd hwang
ftp 166.111.2.177
anonymous
<-
get arm.tar.gz
get kernel.tar.gz
get root-for-nfs-v5.tar.gz
2.setup cross-compiler for arm linux kernel
cp arm.tar.gz /usr/local
cd /usr/local
tar xvzf arm.tar.gz
/*edit PATH */
cd /etc
vi profile
/*change PATH=/usr/local/arm/2.95.3/bin:$PATH*/
3.change rootfs for our needed version
cd /root/hwang
cp root-for-nfs-v5.tar.gz /source/
mv rootfs rootfs_old
tar xvzf root-for-nfs-v5.tar.gz
mv root rootfs
4. unpack the kernel package
cd /root/hwang
tar xvzf kernel.tar.gz
cd kernel
/*now start to add a new board in this kernel*/
5. edit and change arch/arm/config.in
vi arch/arm/config.in
/* in choice <<'ARM system type'>>
add a new line after << S3C2410-based CONFIG_ARCH_S3C2410 \\>>
FS2410-based CONFIG_ARCH_FS2410 \
*/
/*in this section "if [ "$CONFIG_ARCH_EBSA110" = "y" -o
"$CONFIG_FOOTBRIDGE" = "y" -o \
"$CONFIG_ARCH_TBOX" = "y" -o "$CONFIG_ARCH_SHARK" = "y"
-o \
"$CONFIG_ARCH_NEXUSPCI" = "y" -o "$CONFIG_ARCH_CLPS711X" = "y"
-o \
"$CONFIG_ARCH_INTEGRATOR" = "y" -o "$CONFIG_ARCH_SA1100" = "y"
-o \
"$CONFIG_ARCH_L7200" = "y" -o "$CONFIG_ARCH_ANAKIN" = "y" -o
\
"$CONFIG_ARCH_S3C2400" = "y" -o "$CONFIG_ARCH_S3C2410" = "y" -o
\
"$CONFIG_ARCH_CAMELOT" = "y" -o "$CONFIG_ARCH_MX1ADS" = "y"
]; then
define_bool CONFIG_CPU_32v4 y
else
define_bool CONFIG_CPU_32v4 n
fi
add a new option like this
if [ "$CONFIG_ARCH_EBSA110" = "y" -o "$CONFIG_FOOTBRIDGE" = "y"
-o \
"$CONFIG_ARCH_TBOX" = "y" -o "$CONFIG_ARCH_SHARK" = "y"
-o \
"$CONFIG_ARCH_NEXUSPCI" = "y" -o "$CONFIG_ARCH_CLPS711X" = "y"
-o \
"$CONFIG_ARCH_INTEGRATOR" = "y" -o "$CONFIG_ARCH_SA1100" = "y"
-o \
"$CONFIG_ARCH_L7200" = "y" -o "$CONFIG_ARCH_ANAKIN" = "y" -o
\
"$CONFIG_ARCH_S3C2400" = "y" -o "$CONFIG_ARCH_S3C2410" = "y" -o
\
"$CONFIG_ARCH_CAMELOT" = "y" -o "$CONFIG_ARCH_MX1ADS" = "y"
-o \
"$CONFIG_ARCH_FS2410" = "y"]; then
define_bool CONFIG_CPU_32v4 y
else
define_bool CONFIG_CPU_32v4 n
fi
after this section [if [ "$CONFIG_ARCH_S3C2410" = "y" ]; then
comment 'S3C2410 Implementation'
dep_bool ' SMDK (MERI TECH BOARD)' CONFIG_S3C2410_SMDK
$CONFIG_ARCH_S3C2410
dep_bool ' change AIJI' CONFIG_SMDK_AIJI
dep_tristate 'S3C2410 USB function support' CONFIG_S3C2410_USB
$CONFIG_ARCH_S3C2100
dep_tristate ' Support for S3C2410 USB character device emulation'
CONFIG_S3C2410_USB_CHAR $CONFIG_S3C2410_USB
fi # /* CONFIG_ARCH_S3C2410 */
add a new section like this
if [ "$CONFIG_ARCH_FS2410" = "y" ]; then
comment 'FS2410 Implementation'
dep_bool ' SMDK (MERI TECH BOARD)' CONFIG_FS2410_SMDK
$CONFIG_ARCH_FS2410
dep_bool ' change AIJI' CONFIG_SMDK_AIJI
dep_tristate 'S3C2410 USB function support' CONFIG_FS2410_USB
$CONFIG_ARCH_FS2100
dep_tristate ' Support for S3C2410 USB character device emulation'
CONFIG_FS2410_USB_CHAR $CONFIG_FS2410_USB
fi # /* CONFIG_ARCH_S3C2410 */
in this section [# ARM920T
if [ "$CONFIG_ARCH_S3C2400" = "y" -o "$CONFIG_ARCH_S3C2410" = "y" -o \
"$CONFIG_ARCH_MX1ADS" = "y" ]; then
define_bool CONFIG_CPU_ARM920T y
else
if [ "$CONFIG_ARCH_INTEGRATOR" = "y" ]; then
bool 'Support ARM920T processor' CONFIG_CPU_ARM920T
else
define_bool CONFIG_CPU_ARM920T n
fi
fi
add a new line like this
# ARM920T
if [ "$CONFIG_ARCH_S3C2400" = "y" -o "$CONFIG_ARCH_S3C2410" = "y" -o \
"$CONFIG_ARCH_MX1ADS" = "y" -o "$CONFIG_ARCH_FS2410" = "y"]; then
define_bool CONFIG_CPU_ARM920T y
else
if [ "$CONFIG_ARCH_INTEGRATOR" = "y" ]; then
bool 'Support ARM920T processor' CONFIG_CPU_ARM920T
else
define_bool CONFIG_CPU_ARM920T n
fi
fi
int this section if [ "$CONFIG_FOOTBRIDGE_HOST" = "y" -o \
"$CONFIG_ARCH_SHARK" = "y" -o \
"$CONFIG_ARCH_CLPS7500" = "y" -o \
"$CONFIG_ARCH_EBSA110" = "y" -o \
"$CONFIG_ARCH_CDB712" = "y" -o \
"$CONFIG_ARCH_EDB7211" = "y" -o \
"$CONFIG_ARCH_S3C2400" = "y" -o \
"$CONFIG_ARCH_S3C2410" = "y" -o \
"$CONFIG_ARCH_SA1100" = "y" ]; then
define_bool CONFIG_ISA y
else
define_bool CONFIG_ISA n
fi
add a new line like this
if [ "$CONFIG_FOOTBRIDGE_HOST" = "y" -o \
"$CONFIG_ARCH_SHARK" = "y" -o \
"$CONFIG_ARCH_CLPS7500" = "y" -o \
"$CONFIG_ARCH_EBSA110" = "y" -o \
"$CONFIG_ARCH_CDB712" = "y" -o \
"$CONFIG_ARCH_EDB7211" = "y" -o \
"$CONFIG_ARCH_S3C2400" = "y" -o \
"$CONFIG_ARCH_S3C2410" = "y" -o \
"$CONFIG_ARCH_FS2410" = "y" -o \
"$CONFIG_ARCH_SA1100" = "y" ]; then
define_bool CONFIG_ISA y
else
define_bool CONFIG_ISA n
fi
in this section if [ "$CONFIG_ARCH_NETWINDER" = "y" -o \
"$CONFIG_ARCH_EBSA110" = "y" -o \
"$CONFIG_ARCH_EBSA285" = "y" -o \
"$CONFIG_ARCH_FTVPCI" = "y" -o \
"$CONFIG_ARCH_SHARK" = "y" -o \
"$CONFIG_ARCH_CO285" = "y" -o \
"$CONFIG_ARCH_SA1100" = "y" -o \
"$CONFIG_ARCH_LUBBOCK" = "y" -o \
"$CONFIG_ARCH_PXA_IDP" = "y" -o \
"$CONFIG_ARCH_PXA_CERF" = "y" -o \
"$CONFIG_ARCH_INTEGRATOR" = "y" -o \
"$CONFIG_ARCH_CDB712" = "y" -o \
"$CONFIG_ARCH_S3C2410" = "y" -o \
"$CONFIG_ARCH_PREMIUM" = "y" -o \
"$CONFIG_ARCH_NIPC2" = "y" -o \
"$CONFIG_ARCH_P720T" = "y" ]; then
bool 'Timer and CPU usage LEDs' CONFIG_LEDS
if [ "$CONFIG_LEDS" = "y" ]; then
if [ "$CONFIG_ARCH_NETWINDER" = "y" -o \
"$CONFIG_ARCH_EBSA285" = "y" -o \
"$CONFIG_ARCH_SHARK" = "y" -o \
"$CONFIG_ARCH_CO285" = "y" -o \
"$CONFIG_ARCH_SA1100" = "y" -o \
"$CONFIG_ARCH_INTEGRATOR" = "y" -o \
"$CONFIG_ARCH_P720T" = "y" -o \
"$CONFIG_ARCH_LUBBOCK" = "y" -o \
"$CONFIG_ARCH_PXA_CERF" = "y" -o \
"$CONFIG_ARCH_S3C2410" = "y" -o \
"$CONFIG_ARCH_PREMIUM" = "y" -o \
"$CONFIG_ARCH_NIPC2" = "y" -o \
"$CONFIG_ARCH_PXA_IDP" = "y" ]; then
bool ' Timer LED' CONFIG_LEDS_TIMER
bool ' CPU usage LED' CONFIG_LEDS_CPU
fi
if [ "$CONFIG_ARCH_EBSA110" = "y" ]; then
define_bool CONFIG_LEDS_TIMER y
fi
fi
fi
add two new line link this
if [ "$CONFIG_ARCH_NETWINDER" = "y" -o \
"$CONFIG_ARCH_EBSA110" = "y" -o \
"$CONFIG_ARCH_EBSA285" = "y" -o \
"$CONFIG_ARCH_FTVPCI" = "y" -o \
"$CONFIG_ARCH_SHARK" = "y" -o \
"$CONFIG_ARCH_CO285" = "y" -o \
"$CONFIG_ARCH_SA1100" = "y" -o \
"$CONFIG_ARCH_LUBBOCK" = "y" -o \
"$CONFIG_ARCH_PXA_IDP" = "y" -o \
"$CONFIG_ARCH_PXA_CERF" = "y" -o \
"$CONFIG_ARCH_INTEGRATOR" = "y" -o \
"$CONFIG_ARCH_CDB712" = "y" -o \
"$CONFIG_ARCH_S3C2410" = "y" -o \
"$CONFIG_ARCH_FS2410" = "y" -o \
"$CONFIG_ARCH_PREMIUM" = "y" -o \
"$CONFIG_ARCH_NIPC2" = "y" -o \
"$CONFIG_ARCH_P720T" = "y" ]; then
bool 'Timer and CPU usage LEDs' CONFIG_LEDS
if [ "$CONFIG_LEDS" = "y" ]; then
if [ "$CONFIG_ARCH_NETWINDER" = "y" -o \
"$CONFIG_ARCH_EBSA285" = "y" -o \
"$CONFIG_ARCH_SHARK" = "y" -o \
"$CONFIG_ARCH_CO285" = "y" -o \
"$CONFIG_ARCH_SA1100" = "y" -o \
"$CONFIG_ARCH_INTEGRATOR" = "y" -o \
"$CONFIG_ARCH_P720T" = "y" -o \
"$CONFIG_ARCH_LUBBOCK" = "y" -o \
"$CONFIG_ARCH_PXA_CERF" = "y" -o \
"$CONFIG_ARCH_S3C2410" = "y" -o \
"$CONFIG_ARCH_FS2410" = "y" -o \
"$CONFIG_ARCH_PREMIUM" = "y" -o \
"$CONFIG_ARCH_NIPC2" = "y" -o \
"$CONFIG_ARCH_PXA_IDP" = "y" ]; then
bool ' Timer LED' CONFIG_LEDS_TIMER
bool ' CPU usage LED' CONFIG_LEDS_CPU
fi
if [ "$CONFIG_ARCH_EBSA110" = "y" ]; then
define_bool CONFIG_LEDS_TIMER y
fi
fi
fi
int this section if [ "$CONFIG_ARCH_ACORN" = "y" -o \
"$CONFIG_ARCH_CLPS7500" = "y" -o \
"$CONFIG_ARCH_TBOX" = "y" -o \
"$CONFIG_ARCH_SHARK" = "y" -o \
"$CONFIG_ARCH_SA1100" = "y" -o \
"$CONFIG_ARCH_PXA" = "y" -o \
"$CONFIG_ARCH_S3C2400" = "y" -o "$CONFIG_ARCH_S3C2410" = "y" -o \
"$CONFIG_PCI" = "y" ]; then
mainmenu_option next_comment
comment 'Sound'
tristate 'Sound support' CONFIG_SOUND
if [ "$CONFIG_SOUND" != "n" ]; then
source drivers/sound/Config.in
fi
endmenu
fi
add a new line like this
if [ "$CONFIG_ARCH_ACORN" = "y" -o \
"$CONFIG_ARCH_CLPS7500" = "y" -o \
"$CONFIG_ARCH_TBOX" = "y" -o \
"$CONFIG_ARCH_SHARK" = "y" -o \
"$CONFIG_ARCH_SA1100" = "y" -o \
"$CONFIG_ARCH_PXA" = "y" -o \
"$CONFIG_ARCH_S3C2400" = "y" -o "$CONFIG_ARCH_S3C2410" = "y" -o \
"$CONFIG_ARCH_FS2410" = "y" -o \
"$CONFIG_PCI" = "y" ]; then
mainmenu_option next_comment
comment 'Sound'
tristate 'Sound support' CONFIG_SOUND
if [ "$CONFIG_SOUND" != "n" ]; then
source drivers/sound/Config.in
fi
endmenu
fi
int this section
if [ "$CONFIG_S3C2400_GAMEPARK" = "y" -o "$CONFIG_S3C2400_SMDK" = "y"
-o \
"$CONFIG_ARCH_PREMIUM" = "y" -o "$CONFIG_LUBBOCK_MIZI" = "y" -o \
"$CONFIG_SA1100_KINGS" = "y" -o "$CONFIG_SA1100_SUNS_OLD" = "y" -o
\
"$CONFIG_SA1100_G200" = "y" -o "$CONFIG_SA1100_GILL" = "y" -o \
"$CONFIG_SA1100_ALPHA2" = "y" -o "$CONFIG_SA1100_FORTE" = "y" -o \
"$CONFIG_S3C2410_SMDK" = "y" -o "$CONFIG_SA1100_SUNS" = "y" -o \
"$CONFIG_SA1100_WISMO" = "y" -o "$CONFIG_ARCH_NIPC2" = "y"]; then
define_bool CONFIG_MIZI y
else
define_bool CONFIG_MIZI n
fi
add a new line like this
if [ "$CONFIG_S3C2400_GAMEPARK" = "y" -o "$CONFIG_S3C2400_SMDK" = "y"
-o \
"$CONFIG_ARCH_PREMIUM" = "y" -o "$CONFIG_LUBBOCK_MIZI" = "y" -o \
"$CONFIG_SA1100_KINGS" = "y" -o "$CONFIG_SA1100_SUNS_OLD" = "y" -o
\
"$CONFIG_SA1100_G200" = "y" -o "$CONFIG_SA1100_GILL" = "y" -o \
"$CONFIG_SA1100_ALPHA2" = "y" -o "$CONFIG_SA1100_FORTE" = "y" -o \
"$CONFIG_S3C2410_SMDK" = "y" -o "$CONFIG_SA1100_SUNS" = "y" -o \
"$CONFIG_SA1100_WISMO" = "y" -o "$CONFIG_ARCH_NIPC2" = "y" -o \
"$CONFIG_FS2410_SMDK" = "y"]; then
define_bool CONFIG_MIZI y
else
define_bool CONFIG_MIZI n
fi
int this section
if [ "$CONFIG_FOOTBRIDGE_HOST" = "y" -o \
"$CONFIG_ARCH_SHARK" = "y" -o \
"$CONFIG_ARCH_SA1100" = "y" -o \
"$CONFIG_ARCH_PXA" = "y" -o \
"$CONFIG_ARCH_INTEGRATOR" = "y" -o \
"$CONFIG_ARCH_TBOX" = "y" -o \
"$CONFIG_ARCH_CLPS7500" = "y" -o \
"$CONFIG_ARCH_P720T" = "y" -o \
"$CONFIG_ARCH_ANAKIN" = "y" -o \
"$CONFIG_ARCH_S3C2400" = "y" -o "$CONFIG_S3C2410_SMDK" = "y" -o \
"$CONFIG_ARCH_MX1ADS" = "y" ]; then
define_bool CONFIG_PC_KEYMAP y
fi
if [ "$CONFIG_ARCH_ACORN" != "y" -a "$CONFIG_ARCH_EBSA110" != "y" ];
then
bool 'VGA text console' CONFIG_VGA_CONSOLE
fi
source drivers/video/Config.in
endmenu
fi
add a new line like this
if [ "$CONFIG_FOOTBRIDGE_HOST" = "y" -o \
"$CONFIG_ARCH_SHARK" = "y" -o \
"$CONFIG_ARCH_SA1100" = "y" -o \
"$CONFIG_ARCH_PXA" = "y" -o \
"$CONFIG_ARCH_INTEGRATOR" = "y" -o \
"$CONFIG_ARCH_TBOX" = "y" -o \
"$CONFIG_ARCH_CLPS7500" = "y" -o \
"$CONFIG_ARCH_P720T" = "y" -o \
"$CONFIG_ARCH_ANAKIN" = "y" -o \
"$CONFIG_ARCH_S3C2400" = "y" -o "$CONFIG_S3C2410_SMDK" = "y" -o \
"$CONFIG_FS2410_SMDK" = "y" -o "$CONFIG_ARCH_MX1ADS" = "y" ]; then
define_bool CONFIG_PC_KEYMAP y
fi
if [ "$CONFIG_ARCH_ACORN" != "y" -a "$CONFIG_ARCH_EBSA110" != "y" ];
then
bool 'VGA text console' CONFIG_VGA_CONSOLE
fi
source drivers/video/Config.in
endmenu
fi
6. edit arch/arm/Makefile
vi arch/arm/Makefile
after this section
ifeq ($(CONFIG_ARCH_S3C2410),y)
TEXTADDR = 0xC0008000
MACHINE = s3c2410
endif
add a new section like this
ifeq ($(CONFIG_ARCH_FS2410),y)
TEXTADDR = 0xC0008000
MACHINE = fs2410
endif
7. edit arch/arm/boot/Makefile
after this section
ifeq ($(CONFIG_ARCH_S3C2410),y)
ZTEXTADDR = 0x30008000
ZRELADDR = 0x30008000
endif
add a new section
ifeq ($(CONFIG_ARCH_FS2410),y)
ZTEXTADDR = 0x30008000
ZRELADDR = 0x30008000
endif
8. produce a new dir in arch/arm
cp arch/arm/mach-s3c2410 arch/arm/mach-fs2410 -r
9. produce a new dir in include/asm-arm/
cp include/asm-arm/arch-s3c2410 include/asm-arm/arch-fs2410 -r
10. edit arch/arm/tools/mach-types
add a new line in the second to last line like this
smdk2410 FS2410_SMDK SMDK2410 193
11 edit /arch/arm/boot/compressed/Makefile
after this section
ifeq ($(CONFIG_ARCH_S3C2410),y)
OBJS += head-s3c2410.o
endif
addd a new section
ifeq ($(CONFIG_ARCH_FS2410),y)
OBJS += head-fs2410.o
endif
12. produce a new file in arch/arm/boot/compressed/
cp head-s3c2410.S head-fs2410.S
13. change include/asm-arm/arch-fs2410/hardware.h
from #ifdef CONFIG_S3C2410_SMDK
#include "smdk.h"
#endif
to
#ifdef CONFIG_FS2410_SMDK
#include "smdk.h"
#endif
14. change arch/arm/kernel/entry-armv.S
after this section
#elif defined(CONFIG_ARCH_S3C2410)
#include .macro disable_fiq .endm .macro get_irqnr_and_base, irqnr, irqstat, base, tmp mov r4, #INTBASE @ virtual address of IRQ registers ldr \\irqnr, [r4, #0x8] @ read INTMSK ldr \\irqstat, [r4, #0x10] @ read INTPND bics \\irqstat, \\irqstat, \\irqnr bics \\irqstat, \\irqstat, \\irqnr beq 1002f mov \\irqnr, #0 1001: tst \\irqstat, #1 bne 1002f @ found IRQ add \\irqnr, \\irqnr, #1 mov \\irqstat, \\irqstat, lsr #1 cmp \\irqnr, #32 bcc 1001b 1002: .endm .macro irq_prio_table .endm add a new section #elif defined(CONFIG_ARCH_FS2410) #include .macro disable_fiq .endm .macro get_irqnr_and_base, irqnr, irqstat, base, tmp mov r4, #INTBASE @ virtual address of IRQ registers ldr \\irqnr, [r4, #0x8] @ read INTMSK ldr \\irqstat, [r4, #0x10] @ read INTPND bics \\irqstat, \\irqstat, \\irqnr bics \\irqstat, \\irqstat, \\irqnr beq 1002f mov \\irqnr, #0 1001: tst \\irqstat, #1 bne 1002f @ found IRQ add \\irqnr, \\irqnr, #1 mov \\irqstat, \\irqstat, lsr #1 cmp \\irqnr, #32 bcc 1001b 1002: .endm .macro irq_prio_table .endm 15. change the file arch/arm/mach-fs2410/Makefile from O_TARGET := s3c2410.o to O_TARGET := fs2410.o 16. change the file arch/arm/kernel/Makefile from the section no-irq-arch := $(CONFIG_ARCH_INTEGRATOR) $(CONFIG_ARCH_CLPS711X) \ $(CONFIG_FOOTBRIDGE) $(CONFIG_ARCH_EBSA110) \ $(CONFIG_ARCH_SA1100) $(CONFIG_ARCH_CAMELOT) \ $(CONFIG_ARCH_S3C2400) $(CONFIG_ARCH_S3C2410) \ $(CONFIG_ARCH_MX1ADS) $(CONFIG_ARCH_PXA) to the section no-irq-arch := $(CONFIG_ARCH_INTEGRATOR) $(CONFIG_ARCH_CLPS711X) \ $(CONFIG_FOOTBRIDGE) $(CONFIG_ARCH_EBSA110) \ $(CONFIG_ARCH_SA1100) $(CONFIG_ARCH_CAMELOT) \ $(CONFIG_ARCH_S3C2400) $(CONFIG_ARCH_S3C2410) \ $(CONFIG_ARCH_MX1ADS) $(CONFIG_ARCH_PXA) $(CONFIG_ARCH_FS2410) 17. edit arch/arm/mach-fs2410/Makefile change CONFIG_S3C2410_SMDK TO CONFIG_FS2410_SMDK 18. edit drivers/serial/config.in from dep_bool 'S3C2400 serial port support' CONFIG_SERIAL_S3C2400 $CONFIG_ARCH_S3C2400 dep_bool ' Console on S3C2400 serial port' CONFIG_SERIAL_S3C2400_CONSOLE $CONFIG_SERIAL_S3C2400 dep_bool 'S3C2410 serial port support' CONFIG_SERIAL_S3C2410 $CONFIG_ARCH_S3C2410 dep_bool ' Console on S3C2410 serial port' CONFIG_SERIAL_S3C2410_CONSOLE $CONFIG_SERIAL_S3C2410 to dep_bool 'S3C2400 serial port support' CONFIG_SERIAL_S3C2400 $CONFIG_ARCH_S3C2400 dep_bool ' Console on S3C2400 serial port' CONFIG_SERIAL_S3C2400_CONSOLE $CONFIG_SERIAL_S3C2400 dep_bool 'S3C2410 serial port support' CONFIG_SERIAL_S3C2410 $CONFIG_ARCH_S3C2410 dep_bool ' Console on S3C2410 serial port' CONFIG_SERIAL_S3C2410_CONSOLE $CONFIG_SERIAL_S3C2410 dep_bool 'S3C2410 serial port support' CONFIG_SERIAL_S3C2410 $CONFIG_ARCH_FS2410 dep_bool ' Console on S3C2410 serial port' CONFIG_SERIAL_S3C2410_CONSOLE $CONFIG_SERIAL_S3C2410 第三天课程:构建嵌入式环境 1: 嵌入式交叉编译环境 2:arm的体系结构 3:arm的汇编指令 环境, uboot kernel编译 kernel的移植 kernel调试 文件系统,部署 应用程序调用内核中的服务,必须通过系统调用,系统调用int 80h 通过系统调用进入到内核空间,也就是cpu的运行级别从3切换到0 比如应用程序调用fopen api,fopen会调用sys_open系统调用 驱动作用: 1:控制硬件设备 ioctl 2: 内核和设备进行通信 3:应用程序通过调用驱动和设备进行通信 4:控制硬件中断 arm体系结构: 组成: ARM处理器 - 控制整个器件 控制器 - 协调系统的重要功能模块 外设 - 提供芯片与外部的所有输入/输出功能,器件间的一些特有 特性就是靠不同的外设来体现的 s3c2410 cpu arm920t x s3c2410x arm cpu L1 cache L2 cache i-cache d-cache 对cpu的cache进行操作,必须用到arm的协处理器指令 Thumb 是一个 16-bits 指令集 优化代码密度 (~65% of ARM ) 提高窄内存操作性能 是ARM指令集的一个功能子集 ARM9以上都采用harvard结构 指令特点: Load/Store体系结构 固定长度指令 硬联控制 流水线 寄存器 流水线 在cpu的一个时钟周期,cpu同时处理流水线中的任务 s3c2410x: 五级流水线 把一条指令分解成五个步骤来做。 FETCH DECODE EXECUTE MEMORY WRITE 环境: 1:串口 超级终端查看串口信息 串口设置 : 波特率115200 数字流控制 无 给板子加上电之后,可以看到bootloader的信息 烧写flash, 通过JTAG烧写uboot ftp://166.111.192.213 far far 或者匿名 用cuteftp来下载 Flash烧写工具 首先在主机上安装并口的驱动, 安装驱动.exe install 确定 退出 运行SJF2410_BIOS.BAT文件 批处理文件 选0 含义:选nandflash k9s1208 选0 含义:表示对k9s1208进行烧写 选0 含义:从偏移地址0开始烧写 sjf2410 /f:uboot.bin bootloader:1:深圳ucdragon的bootloader,优龙的bootloader norflash:已经有了优龙的bootloader,通过优龙的bootloader烧写uboot 烧写工具:DNW DNW也是一个串口工具,在serial port里面选择connect norflash 已经有ucdragon的bootloader nandflash让用户自己烧写uboot 所以通过dnw让ucdragon的bootloader来烧写nandflash 核心板跳线去掉 敲1 表示将文件下载到本地flash上的内存上 在菜单中选择transmit n 2 0 y 通过usb烧写,更新驱动, 进入交叉开发编译环境 1:交叉编译工具 包括:交叉编译器,binutils,gdb工具等等 2:主机上的服务 nfs tftp服务 3:目标板上必须要有tftp的客户端 由uboot来实现的 物理上连接: 串口连接主机和开发板,让开发板信息显示到超级终端或者dnw或者minicom上 网口连接主机和开发板,提供tftp下载和nfs根文件系统加载功能 可以让开发板通过nfs进入linux系统,可以用主机上的资源进行开发调试,在主机上用arm-gcc 编译目标板代码,将生成的文件放到nfs目录下,这样在超级终端或者dnw的嵌入式linux系统里面直接运行该目标文件。 zImage 内核bin文件 rootfs_fs2410.tar.bz2 文件系统 将内核放置到主机上的tftpboot目录下 将文件系统放置到对应的nfs目录 1:在linux里面开启ftp服务 ntsysv 可以查看linux系统里面的服务列表,将vsftpd 选上 linux里面一般用vsftpd作为ftp服务器 vi /etc/vsftpd.user_list vi /etc/vsftpd.ftpusers 将当中的root一行删掉 service vsftpd restart 作用是重启ftp,让新的ftp服务生效 ifconfig eth0 192.168.1.23 同时在windows主机上添加一个ip地址 192.168.1.234(192.168.1.***都可以) 目的是让windows和linux在同一个网络内。 打开cuteftp 连接192.168.1.23 root 111111 ftp里面有putty 终端工具,登陆到linux上 linux下的nfs服务的设置: nfs 网络文件系统,开发阶段需要采用nfs文件系统,其实质就是无盘工作站, 当嵌入式开发完成之后,然后制作文件系统,将文件系统烧写到flash上。 nfs的配置文件: /etc/exports /opt/target/rootfs *(rw,no_root_squash,no_all_squash) /arm-zznux/nfs/rootfs *(rw,no_root_squash,no_all_squash) 第一个字段:要导出的nfs目录, 第二个字段:*(rw,no_root_squash,no_all_squash)权限, 如果需要导出新的nfs,再添加一行 /home *(rw,no_root_squash,no_all_squash) service nfs restart 在nfs里面添加 /opt/target/rootfs *(rw,no_root_squash,no_all_squash) mkdir /opt/target mv rootfs_fs2410.tar.bz2 /opt/target cd /opt/target tar xjvf rootfs_fs2410.tar.bz2 mount 192.168.1.23:/opt/target/rootfs /mnt cd /mnt ls cd / umount /mnt tftp服务,linux下提供简单ftp下载的服务。 tftp服务是linux下的超级服务器xinetd 的子服务,重启tftp服务需要重启xinetd服务 vi /etc/xinetd.d/tftp 将disable =no service xinetd restart service tftp { disable = no socket_type = dgram protocol = udp wait = yes user = root server = /usr/sbin/in.tftpd server_args = -s /tftpboot per_source = 11 cps = 100 2 flags = IPv4 } service xinetd restart cp zImage /tftpboot 这样主机上的环境就设置好了。 在超级终端 进入uboot命令行 print 显示uboot的环境变量 ipaddr=192.168.1.137 serverip=192.168.1.23 ipaddr表示板子的ip地址 serverip表示主机的ip地址 serverip必须和主机ip一致 在uboot命令下 ping 192.168.1.23 host 192.168.1.23 is alive 表示相通 在超级终端输入: tftp 30800000 zImage 表示将zImage内核下载到本地内存30800000处 go 30800000 表示从30800000处启动内核 交叉编译: linux主机上编写helloworld的程序 用交叉编译器来编译hello.c arm-linux-gcc hello.c -o hello 在主机上用arm编译器编译hello.c file hello 可以看到hello是针对arm的,ELF格式 hello: ELF 32-bit LSB executable, ARM, version 1 (ARM), for GNU/Linux 2.4.0, dynamically linked (uses shared libs), not stripped cp hello /opt/target/rootfs 在超级终端可以看到hello cd / ls ./hello libgcc_s.so.1 在linux上: cp /source/rootfs/lib/libgcc_s.so.1 /opt/target/rootfs/lib/ 交叉编译器的构建: arm-linux.tar.gz 在linux上输入: which arm-linux-gcc 在 /etc/profile 最后一样 export PATH=/交叉编译器所在的路径:$PATH source /etc/profile 让profile文件生效 env echo $PATH 交叉编译器 uboot的自启动设置: print bootdelay 1 如果用户不输入回车,uboot按照bootcmd和bootargs启动系统 setenv bootcmd "tftp 30800000 zImage ;go 30800000" setenv bootdelay 1 save reset 第四天:移植u-boot 总结: 1:交叉编译器在linux上的构建 将arm编译器放到linux上,解开 然后将bin所在的路径加到/etc/profile最后面 export PATH=/home/cross/bin:$PATH source /etc/profile 2: 为什么要用nfs nfs:网络文件系统,重点理解文件系统,linux启动,需要内核,init需要文件系统,flash上还没有文件系统 3:为什么要用tftp tftp是一个简单的文件传输协议,开发阶段是在主机上交叉编译内核,内核编译好之后放在主机上,通过tftp方法将内核从主机传到开发板(内存)上,在开发板上运行下载的内核。 uboot#tftp 30800000 zImage; 从主机下载内核到板子的30800000地址,30800000是内存地址 uboot#go 30800000 运行内核 内核运行之后,内核要加载文件系统,从内核参数或者uboot传递给内核的bootargs里面查找要加载的文件系统的具体位置。 uImage bootcmd=tftp 30800000 /arm-zznux/tftpboot/uImage;bootm 30800000 bootargs=root=nfs nfsroot=192.168.1.23:/arm-zznux/nfs/rootfs ip=192.168.1.134 co nsole=ttySAC0,115200 bootargs内核参数,当内核编译成uboot的时候,bootargs传递给内核uImage。 print ipaddr=192.168.1.137 serverip=192.168.1.23 用来tftp下载内核的时候使用 tftp 30800000 zImage zImage默认从serverip:/tftpboot里面寻找 重新设置环境变量 setenv ipaddr 192.168.1.** save uboot部分 嵌入式linux下面常用的bootloader: uboot,vivi,ppcboot,blob,uMon,redboot等等 uboot从ppcboot发展起来, www.sourceforge.net GRUB http://sourceforge.net/projects/u-boot 1:uboot的特点 uboot的特点: U-BOOT支持SCC/FEC以太网、OOTP/TFTP引导、IP和MAC的预置功能,这一点和其它BootLoader(如BLOB和RedBoot等)类似。但U-BOOT还具有一些特有的功能。 ◆ 在线读写Flash、DOC、IDE、IIC、EEROM、RTC,其它的BootLoader根本不支持IDE和DOC的在线读写。 nand read 0x40000 nand write ◆ 支持串行口kermit和S-record下载代码,U-BOOT本身的工具可以把ELF32格式的可执行文件转换成为 S-record格式,直接从串口下载并执行。 ◆ 识别二进制、ELF32、uImage格式的Image,对Linux引导有特别的支持。U-BOOT对Linux 内核进一步封装为uImage。封装如下: #{CROSS_COMPILE}-objcopy -O binary -R.note -R.comment -S vmlinux \ linux.bin #gzip -9 linux.bin #tools/mkimage -A arm -O linux -T kernel -C gzip -a 0xc0008000 -e\ 0xc0008000 -n “Linux-2.4.20” -d linux.bin.gz /tftpboot/uImage 即在Linux内核镜像vmLinux前添加了一个特殊的头,这个头在include/image.h中定义,包括目标操作系统的种类(比如Linux,VxWorks等)、目标CPU的体系机构(比如ARM、PowerPC等)、映像文件压缩类型(比如gzip、bzip2等)、加载地址、入口地址、映像名称和映像的生成时间。当系统引导时,U-BOOT会对这个文件头进行CRC校验,如果正确,才会跳到内核执行。如下所示: WT-ARM9# bootm 0xc1000000 ## Checking Image at 0xc100000 . Image Name: Linux-2.4.20 Created: 2004-07-02 22:10:11 UTC Image Type: ARM Linux Kernel Image (gzip compressed) Data Size: 550196 Bytes = 537 kB = 0 MB Load Address: 0xc0008000 Entry Point: 0xc0008000 Verifying Checksum . OK Uncompressing Kernel Image ……… OK ◆ 单任务软件运行环境。U-BOOT可以动态加载和运行的应用程序,这些的应用程序可以利用U-BOOT控制台的I/O函数、内存申请和中断服务等。这些应用程序还可以在没有操作系统的情况下运行,是测试硬件系统很好的工具。 ◆ 监控(minitor)命令集:读写I/O,内存,寄存器、内存、外设测试功能等 支持WatchDog、LCD logo和状态指示功能等。如果系统支持splash screen,U-BOOT启动时,会把这个图像显示到LCD上,给用户更友好的感觉。 ◆ 支持MTD和文件系统。U-BOOT作为一种强大的BootLoader,它不仅支持MTD,而且可以在MTD基础上实现多种文件系统,比如cramfs、fat和jffs2等。 ◆ 支持中断。由于传统的BootLoader都分为stage1和stage2,所以在stage2中添加中断处理服务十分困难,比如BLOB;而U-BOOT是把两个部 分放到了一起,所以添加中断服务程序就很方便。 ◆ 详细的开发文档。由于大多数BootLoader都是开源项目,所以文档都不是很充分。U-BOOT的维护人员意识到了这个问题,充分记录了开发文档,所以它的移植要比BLOB等缺少文档的BootLoader方便。 uboot的源代码分析: arm的汇编 跳转指令 数据处理指令 程序状态寄存器传送指令 Load/Store指令 协处理器指令 异常中断产生指令 跳转指令: x86: goto call invoke arm: b lable: mov r1, #FF b lable b不带返回的跳转 r14 bl 带返回的跳转 用到r14保存pc 数据处理指令 mov r1 , #FF arm的合法立即数 mov r2 , #ABCDEF12 arm立即数:8bit的数右移偶数位得到 mov r3, #F01 F01 : 1111 0000 0001 F01能不能由 一个8bit的数 循环右移 ? 位能够得到该数 右移的位数必须是偶数 00 00 0F 01 32bit里面 r1 = FF8 mov r1 , #FF8 × mov r1, #FF, 28 r1=FF0 orr r1, r1, #8 r1 = FF8 ADD Sub Mul ADD r2, r2, r3 r2=r2+r3 SUBS r1, r1, #0x01 算术指令:ADD ADC SUB SBC RSB RSC 逻辑指令:AND ORR EOR BIC 比较指令:CMP CMN TST TEQ 数据搬移:MOV MVN 数据处理指令的时候,只能够 寄存器和寄存器之间操作 或者寄存器和立即数操作,或者寄存器和内存操作, 但是不能内存和内存操作 × 程序状态控制指令 cpsr 当前程序状态寄存器 spsr 备份程序状态寄存器 load/store load: 将内存中的数load到寄存器 store:将寄存器的值存到内存中 共有3种Load-Store指令 ① 单寄存器传送指令 ② 多寄存器传送指令 ③ 交换指令 LDR STR Word 32bit LDR{ STR{ int a= [r2] b= [r3] b=a LDR r1, [r2] STR r1, [r3] LDM STM 多寄存器传送 LDM r10, {r0,r1,r4} r10是r0,r1,r4的基址 STM r10, {r0,r1,r4} ARM体系支持16个协处理器 u-boot.1.1.4源代码 U-BOOT源代码目录结构 ◆ board: 存放开发板:一些已有开发板有关的文件,比如Makefile和u-boot.lds等都和具体开发板的硬件和地址分配有关。 uboot已经支持的开发板。 smdk2410 ai2410 dm9000 cs00 csb272 做得是板子的初始化工作以及flash的初始化工作。 ◆ common:与体系结构无关的文件,实现uboot各种命令的C文件。 以cmd打头的.c文件 uboot下的各个命令 go bootm setenv etc ◆ cpu: 放cpu相关代码 s3c2410的cpu,cpu用的是arm920的核, fs2410板子的cpu代码:cpu\\arm920t\\s3c24x0 CPU相关文件,其中的子目录都是以U-BOOT所支持的CPU为名,比如有子目录arm920、mips、mpc8260和nios等,每个特定的子目录中都包括cpu.c和interrupt.c,start.S。其中cpu.c初始化CPU、设置指令Cache和数据Cache等;interrupt.c设置系统的各种中断和异常,比如快速中断、开关中断、时钟中断、软件中断、预取中止和未定义指令等;start.S是U-BOOT启动时执行的第一个文件,它主要是设置系统堆栈和工作方式,为进入C程序奠定基础。 ◆ disk:disk驱动的分区处理代码。 ◆ doc:文档。 ◆ drivers:通用设备驱动程序,比如各种网卡、支持CFI的Flash、串口和USB总线等。 dm9000,cs00, ◆ fs:支持文件系统的文件,U-BOOT现在支持cramfs、fat、fdos、jffs2和registerfs。 ◆ include:头文件,还有对各种硬件平台支持的汇编文件,系统的配置文件和对文件系统支持的文件。 include/configs/ai2410.h include/configs/smdk2410.h 配置文件放在include目录下 ◆ net:与网络有关的代码,BOOTP协议、TFTP协议、RARP协议和NFS文件系统的实现。 ◆ lib_arm:与ARM体系结构相关的代码。 ◆ tools:创建S-Record格式文件 和U-BOOT images的工具。 mkimage:tools目录下,用来制作uImage。 用tools下的工具制作脚本文件。 README u-boot-1.1.4/board/ai2410/u-boot.lds linux下的lds作用: OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") /*OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/ OUTPUT_ARCH(arm) ENTRY(_start) SECTIONS { . = 0x00000000; . = ALIGN(4); .text : { cpu/arm920t/start.o (.text) *(.text) } . = ALIGN(4); .rodata : { *(.rodata) } . = ALIGN(4); .data : { *(.data) } . = ALIGN(4); .got : { *(.got) } . = .; __u_boot_cmd_start = .; .u_boot_cmd : { *(.u_boot_cmd) } __u_boot_cmd_end = .; . = ALIGN(4); __bss_start = .; .bss : { *(.bss) } _end = .; } cpu/arm920t/start.o cpu/arm920t/start.S 首先重定位uboot在内存中的位置 然后建立栈 stack 然后做bss段的清零工作 ldr pc, _start_armboot _start_armboot在 lib-arm/board.c里面定义 分两步的过程,第一步start.S 第二步board.c lib_arm/board.c void start_armboot (void) cpu_init, /* basic cpu dependent setup */ board_init, /* basic board dependent setup */ interrupt_init, /* set up exceptions */ env_init, /* initialize environment */ init_baudrate, /* initialze baudrate settings */ serial_init, /* serial communications setup */ console_init_f, /* stage 1 init of console */ display_banner, /* say that we are here */ dram_init, /* configure available RAM banks */ display_dram_config, #if defined(CONFIG_VCMA9) || defined (CONFIG_CMC_PU2) checkboard, #endif NULL, board_init 在board/smdk2410.c里面定义 uboot的过程: 分成了两个阶段: start.S第一阶段: start_armboot:第二阶段: 2:uboot的编译: uboot的编译命令: 解压后进入uboot的源代码目录, 比如编译smdk2410能运行的uboot, 输入: cd u-boot-1.1.4/ make smdk2410_config make 编译出针对smdk2410开发板的uboot Makefile /smdk2410_config @./mkconfig $(@:_config=) arm arm920t smdk2410 NULL s3c24x0 uboot可以在smdk2410上用 u-boot.bin 将u-boot.bin拷贝到 合并代码工具: 然后执行combin.bat 功能是将nandboot和u-boot.bin合并 生成uboot.bin uboot.bin文件就是最后的目标文件 DNW + 优龙的bootloader 烧写uboot 烧写到nandflash,插上跳线。 Makefile a:hello.c gcc -o hello hello.c make 移植步骤: 1:选定一个参考板,选定一个最接近现在板子作为参照 比如smdk2410和ai2410就比较接近现在的开发板,ai2410除了网卡,其他的配置都相同,smdk2410网卡和现在板子一样,其他有差异。 比如,就选择ai2410作为参考板,开始移植 2:选定板子的名字 比如fs2410 3:在板子目录下 cd board mkdir fs2410 cp -a ai2410/* fs2410/ cd fs2410 ls mv ai2410.c fs2410.c mv ai2410.h fs2410.h vi Makefile 把 ai2410.o改成fs2410.o vi fs2410.c 把ai2410.h 改成 fs2410.h 把板子相关的部分代码补齐了。 cd ../.. cp include/configs/ai2410.h include/configs/fs2410.h 修改Makefile文件 查找ai2410 仿照ai2410_config添加 fs2410_config 然后 make fs2410_config make 针对板子进行源代码的修改 vi include/configs/fs2410.h 记录了板子相关的硬件配置信息 /DM9000 在第二个终端打开 vi include/configs/smdk2410.h /CS00 把smdk2410.h里面对cs00的定义全部拷贝到fs2410.h里面去 已经在uboot当中加入了对cs00的驱动 3:uboot的移植 首先找一个参考板: 所有改动都在参考板的基础上改动 ai2410: 网卡dm9000,100M网卡 fs2410: 网卡cs00,10M网卡 1:在board目录下 新建一个fs2410目录 cd board mkdir fs2410 cp -a ai2410/* fs2410 2: 在include/configs/里面新加fs2410.h cp include/configs/ai2410.h include/configs/fs2410.h 3:修改Makefile文件 查找ai2410_config出现的地方, 在ai2410_config配置后面添加如下: fs2410_config: undef 等。 4:make fs2410_config make 确保不出错 在include/configs/fs2410.h DM9000: 800000 硬件手册。 fs2410.h定义cs00的基址 19000300 参考smdk2410.h里面对cs00的声明,将cs00的部分全部考到fs2410.h,替换对dm9000的声明。 修改cs00的驱动,将比较网卡ID的代码注释掉。 drivers/cs00.c 搜索0x630e 两处出现: get_eth** eth_init make 1:Makefile hello.c 1:autoscan 2: mv configure.scan configure.in # Process this file with autoconf to produce a configure script. AC_PREREQ(2.57) AC_INIT(hello.c) AM_INIT_AUTOMAKE(hello, 1.0) # Checks for programs. AC_PROG_CC # Checks for libraries. # Checks for header files. # Checks for typedefs, structures, and compiler characteristics. # Checks for library functions. AC_OUTPUT(Makefile) 3:aclocal 4:autoconf 5:新建 Makefile.am AUTOMAKE_OPTION=foreign bin_PROGRAMS=hello 6:automake --add-missing 7:./configure 8:make 手工写makefile文件 fs2410.h文件 PHYS_FLASH_SIZE norflash的大小 改成2M make vi drivers/cs00.c /0x630e 将出现的代码注释掉 将两个地方出现的代码都注释掉 make clean make fs2410_config make u-boot.bin 文件 第五天:调试 linux内核的调试 1:软件调试 printk kgdb LED proc 2:硬件调试 BDI ICE 等等 printk和proc方法调试内核方便 kgdb需要移植kgdb到内核当中 LED GPIO连接到指示灯 BDI和ICE需要硬件调试器的支持。 IAR ADS模拟调试 ftp://166.111.192.236 far far 下载 2.6.11.good.tar.gz 在linux上解压缩 tar xzvf 2.6.11.good.tar.gz 1,Printk 函数打印调试信息 2,Kgdb 调试程序 3,Watch Oops and Panic 查看临死前现场的打印信息 4,Light LED 点LED灯调试 printk类似应用程序中的printf kernel/printk.c printk函数将要打印的消息放到mesgbuf,当系统调用flush,将mesgbuf数据显示到终端。 buf的大小可以在编译内核的时候指定, make menuconfig kernel hacking :用来开启内核调试上的一些选项。 一般在kernel hacking菜单中 1: kernel log buffer size 14 (1<<14) 16k 2: debug preemptive kernel 3: verbose user fault messages 4: kernel low-level debug 5:s3c2410 uart used for low-level debug 直接对串口寄存器进行 赋值的操作 vi include/asm-arm/arch/regs-serial.h 包含了对串口寄存器的值,可以从该文件中看到串口寄存器。 通过对串口的寄存器直接赋值,可以打印串口的信息出来。 很重要,可以用,init/main.c里面添加串口寄存器定义文件,然后加入www函数,然后直接对串口寄存器赋值 #if 1 int www_delay(int sed) { int i; while(sed--) { i = 0x1000; while(i--); } return 0; } #endif 然后加入直接对串口寄存器读写的操作: #if 1 for(i = 0;i < 100;i++){ *(volatile unsigned long*)(S3C24XX_VA_UART0+S3C2410_UTXH) = command_line[i]; www_delay(1000); } *(volatile unsigned long*)(S3C24XX_VA_UART0+S3C2410_UTXH) = 'e'; #endif linux 启动流程 linux/arch/arm/boot/compressed/head.S head.S -> uncompress kernel -> 直接对pc进行赋值, linux/arch/arm/kernel/head.S ->start_kernel init/main.c 调用start_kernel之后,要对板子进行一系列的初始化工作,在初始化工作的时候可能出错。 vi init/main.c start_kernel() 函数里面增加printk的方法,也可以增加对串口寄存器直接赋值操作。 1:添加头文件 #include 2:加到 asmlinkage void __init start_kernel(void) 函数前面 #if 1 int www_delay(int sed) { int i; while(sed--) { i = 0x1000; while(i--); } return 0; } #endif 在start_kernel函数里面 setup_arch()调用后面加上 #if 1 for(i = 0;i < 100;i++){ *(volatile unsigned long*)(S3C24XX_VA_UART0+S3C2410_UTXH) = command_line[i]; www_delay(1000); } *(volatile unsigned long*)(S3C24XX_VA_UART0+S3C2410_UTXH) = 'e'; #endif 串口的使用只能在setup_arch成功之后, start_kernl() ->setup_arch(&command_line); 将main.c替换 init/main.c vi init/main.c if 0 setup_arch() 后面的if 0改成 if 1 然后直接编译内核 make setup_arch()建立物理地址和虚拟地址映射关系,往串口寄存器中写字符需要在setup_arch()之后才可以。 printk主要是调试驱动 oops: 内核出现错误,内核崩溃。把崩溃前的一系列信息打印出来。 当前指令的地址 EIP LR 函数调用栈 frame 判断内核在哪个地方出错。 panic方法 nfs文件系统没有设置好, panic vfs init panic是在代码里面指定。 init/main.c init() { if (execute_command) run_init_process(execute_command); run_init_process("/sbin/init"); run_init_process("/etc/init"); run_init_process("/bin/init"); run_init_process("/bin/sh"); panic("No init found. Try passing init= option to kernel."); } 所以当nfs文件系统没有构建好的时候,内核会报告 "No init found. Try passing init= option to kernel." panic("") printk+abort 错误 proc的应用 proc 虚拟的文件系统,内核启动之后出现。 关机之后消失。 proc反应当前系统中的信息。 用proc可以查看驱动,设备,内存等等,用来辅助调试内核。 cat /proc/cmdline 查看内核参数 cat /proc/meminfo 查看内存,看内存是否和物理内存大小一致 cat /proc/mtd 看flash的分区是否正确等等。 跟踪调试内核的单步执行: 1:gdb +KGDB 主机上用gdb作为客户端 开发板用KGDB作为内核的gdb桩 通过gdb调试内核就仿佛调试应用程序一样。 当内核打上kgdb桩后,内核会停在断点处,等待主机发来调试信息。 流程和正常内核启动流程不一样,正常内核启动是setup_arch()之后做其他boot,而kgdb则走另外一个流程 2:用BDI2000 arbatron公司,swiss JTAG接口控制 不光调试内核,还可以调试bootloader 通过bdi2000可以直接控制目标板cpu的执行流程 通过gdb调试内核 在主机用 arm-linux-gdb vmlinux target remote bdi 让gdb登陆到bdi上, 再用gdb设置断点,单步执行等等。 交叉调试的范畴, 利用gdb交叉调试linux,(linux内核,linux应用程序) IAR和ADS IAR sweden IDE开发工具 IAR采用J-LINK方式,主机和IAR调试器通过usb,IAR调试器和目标机通过JTAG连接 IAR也是通过JTAG调试目标板,比gdb友好, IAR可以脱离硬件直接进行仿真。 ADS是arm公司的 arm development suitcase 也是一个集开发调试一体的IDE工具 通过 linux2.6.11.error.tar.gz修改正确 调试内核 cross gdb