注:
原文出自taoyuetao大侠的博客上:
http://www.eetop.cn/blog/html/45/11145_itemid_1746.html
小弟参考之研究s3c2410相关代码,然后做了稍微的修改,作为一个学习笔记,方便以后的学习,也希望对后人有所帮助^_^
函数__create_page_tables介绍:
假设内核起始物理地址是0x30008000,虚拟地址是0xC0008000,下面的代码是建立内核起始处4MB空间的映射,
采用了一级映射方式,即段式(section)映射方式,每段映射范围为1MB空间。于是需要建立4个表项,实现:
虚拟地址0xC0000000~0xC0300000,映射到物理地址0x30000000~0x30300000。
.macro pgtbl, reg, rambase
adr \reg, stext
sub \reg, \reg, #0x4000
.endm
.macro krnladr, rd, pgtable, rambase
bic \rd, \pgtable, #0x000ff000
.endm
/*
*
Setup the initial page tables. We only
setup the barest
*
amount which are required to get the kernel running, which
*
generally means mapping in the kernel code.
*
*
r8 = machinfo
*
r9 = cpuid
*
r10 = procinfo
*
*
Returns:
* r0,
r3, r5, r6, r7 corrupted
* r4 =
physical page table address
*/
.type __create_page_tables, %function
__create_page_tables:
ldr r5, [r8, #MACHINFO_PHYSRAM] @ physram r5=0x30000000
pgtbl r4, r5 @
page table address r4=0x30004000
/*
* Clear the 16K level 1 swapper page table
*/
mov r0, r4
mov r3, #0
add r6, r0, #0x4000
1: str r3, [r0], #4
str r3, [r0], #4
str r3, [r0], #4
str r3, [r0], #4
teq r0, r6
bne 1b
ldr r7, [r10, #PROCINFO_MMUFLAGS] @ mmuflags //r7=0x00000c1e
/*
* r7用于设置第一级表描述符之用:
* AP :11(读/写权限)
* 域 :0000
* C : 1(高速缓存)
* B : 1 (缓冲)
* bit[1
0] :10(标识此为节描述符)
*/
/*
* Create identity mapping for first MB of
kernel to
* cater for the MMU enable. This identity mapping
* will be removed by paging_init(). We use our current program
* counter to determine corresponding section
base address.
*
* 为以后MMU的开启准备好内存头1M空间的转换表,
* 采用平板地址映射模式(表索引==节基址)
*/
mov r6, pc, lsr #20 @
start of kernel section //r6=0x00000300
orr r3, r7, r6, lsl #20 @ flags + kernel base //r3=0x30000c1e
str r3, [r4, r6, lsl #2] @ identity mapping //[0x30004c00]=0x30000c1e
/* 结果:
* 虚拟地址 物理地址
* 0x300000000 0x30000000。
/*
* Now setup the pagetables for our kernel
direct
* mapped region. We round TEXTADDR down to the
* nearest megabyte boundary. It is assumed that
* the kernel fits within 4 contigous 1MB
sections.
*
*为内核占用的头4M地址准备好转换表(在这采用的就不是平板地址映射模式了)
/
add r0, r4,
#(TEXTADDR & 0xff000000) >> 18 //ro=0x30007000
str r3, [r0, #(TEXTADDR & 0x00f00000) >> 18]! @ KERNEL
+ 0MB
add r3, r3, #1 << 20 //r3=0x30100c1e
str r3, [r0, #4]! @ KERNEL + 1MB
add r3, r3, #1 << 20 //r3=0x30200c1e
str r3, [r0, #4]! @ KERNEL + 2MB
add r3, r3, #1 << 20 //0x30300c1e
str r3, [r0, #4] @ KERNEL + 3MB
/*
* 结果:
* 虚拟地址 物理地址
0xc0000000 0x30000000
0xc0100000 0x30100000
0xc0200000 0x30200000
0xc0300000 0x30300000
*/
/*
* Then map first 1MB of ram in case it
contains our boot params.
*
* 映射sdram的头1M以防boot params需要(不是已经映射过了吗?)
*/
add r0, r4, #VIRT_OFFSET >> 18 //r0=0x30007000
orr r6, r5, r7 //r6=0x30000c1e
str r6, [r0] //[0x30007000]=0x3000c1e
#ifdef CONFIG_XIP_KERNEL
/*
* Map some ram to cover our .data and .bss
areas.
* Mapping 3MB should be plenty.
*/
sub r3, r4, r5
mov r3, r3, lsr #20
add r0, r0, r3, lsl #2
add r6, r6, r3, lsl #20
str r6, [r0], #4
add r6, r6, #(1 << 20)
str r6, [r0], #4
add r6, r6, #(1 << 20)
str r6, [r0]
#endif
#ifdef CONFIG_DEBUG_LL
bic r7, r7, #0x0c @
turn off cacheable
@
and bufferable bits
/*
* Map in IO space for serial debugging.
* This allows debug messages to be output
* via a serial console before paging_init.
*/
ldr r3, [r8, #MACHINFO_PGOFFIO]
add r0, r4, r3
rsb r3, r3, #0x4000 @
PTRS_PER_PGD*sizeof(long)
cmp r3, #0x0800 @
limit to 512MB
movhi r3, #0x0800
add r6, r0, r3
ldr r3, [r8, #MACHINFO_PHYSIO]
orr r3, r3, r7
1: str r3, [r0], #4
add r3, r3, #1 << 20
teq r0, r6
bne 1b
#if defined(CONFIG_ARCH_NETWINDER) ||
defined(CONFIG_ARCH_CATS)
/*
* If we're using the NetWinder, we need to map
in
* the 16550-type serial port for the debug
messages
*/
teq r1, #MACH_TYPE_NETWINDER
teqne r1, #MACH_TYPE_CATS
bne 1f
add r0, r4, #0xff000000 >> 18
orr r3, r7, #0x7c000000
str r3, [r0]
1:
#endif
#ifdef CONFIG_ARCH_RPC
/*
* Map in screen at 0x02000000 &
SCREEN2_BASE
* Similar reasons here - for debug. This is
* only for Acorn RiscPC architectures.
*/
add r0, r4, #0x02000000 >> 18
orr r3, r7, #0x02000000
str r3, [r0]
add r0, r4, #0xd8000000 >> 18
str r3, [r0]
#endif
#endif
mov pc, lr
posted @
2007-08-02 12:09 lfc 阅读(1781) |
评论 (0) |
编辑 收藏
注:
原文出自taoyuetao大侠的博客上:
http://www.eetop.cn/blog/html/45/11145_itemid_1512.html
小弟参考之研究s3c2410相关代码,然后做了稍微的修改,作为一个学习笔记,方便以后的学习,也希望对后人有所帮助^_^
前一篇介绍了汇编函数__lookup_processor_type,
这一篇介绍__lookup_architecture_type函数
函数__lookup_architecture_type介绍:
每个机器(一般指的是某一个电路板)都有自己的特殊结构,如物理内存地址,物理I/O地址,显存起始地址等等,
这个结构为struct machine_desc,定义在asm-arm/mach/arch.h中:
struct machine_desc {
/*
* Note! The first five elements are used
* by assembler code in head-armv.S
*/
unsigned
int nr; /* architecture number */
unsigned
int phys_ram; /* start of physical ram */
unsigned
int phys_io; /* start of physical io */
unsigned
int io_pg_offst; /* byte offset for io
* page tabe entry */
const
char *name; /* architecture name */
unsigned
long boot_params; /* tagged list */
unsigned
int video_start; /* start of video RAM */
unsigned
int video_end; /* end of video RAM */
unsigned
int reserve_lp0 :1; /* never has lp0 */
unsigned
int reserve_lp1 :1; /* never has lp1 */
unsigned
int reserve_lp2 :1; /* never has lp2 */
unsigned
int soft_reboot :1; /* soft reboot */
void (*fixup)(struct machine_desc *,
struct tag *, char **,
struct meminfo *);
void (*map_io)(void);/* IO mapping
function */
void (*init_irq)(void);
struct
sys_timer *timer; /* system tick timer */
void (*init_machine)(void);
};
这个结构一般都定义在(以arm平台为例)kernel\arch\arm\mach-xxx\xxx.c中,是用宏来定义的,以s3c2410的开发板为例:
定义在kernel\arch\arm\mach-s3c2410\mach-smdk2410.c文件中,如下所示:
MACHINE_START(SMDK2410, "SMDK2410") /* @TODO: request a new
identifier and switch to SMDK2410 */
/*
Maintainer: Jonas Dietsche */
.phys_ram = S3C2410_SDRAM_PA,
.phys_io = S3C2410_PA_UART,
.io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C2410_SDRAM_PA
+ 0x100,
.map_io = smdk2410_map_io,
.init_irq = smdk2410_init_irq,
.timer = &s3c24xx_timer,
MACHINE_END
这些宏也定义在kernel/include/asm-arm/mach/arch.h中,以MACHINE_START为例:
#define MACHINE_START(_type,_name) \
const struct machine_desc
__mach_desc_##_type \
__attribute__((__section__(".arch.info.init")))
= { \
.nr = MACH_TYPE_##_type, \
.name = _name,
#define MACHINE_END \
};
展开之后结构的是:
__mach_desc_SMDK2410= {
.nr = MACH_TYPE_SMDK2410,
.name = "SMDK2410",
中间的1行__attribute__((__section__(".arch.info")))
= {说明将这个结构放到指定的段.arch.info中,这和前面的
.proc.info是一个意思,__attribute__((__section__的含义参考GNU手册。后面的宏都是类似的含义,这里就不再一一介绍。
下面开始说明源码:
第1行实现r3指向3b的地址,3b如__lookup_processor_type介绍的第19行,
第3行将r3所指向的数据区的数据读出到r4,r5,r6,执行结果是
R5= __arch_info_begin,r6= __arch_info_end,r4=第19行的地址
用仿真器查看:
R5= 0xc0018694
R6= 0xc00186cc
R4= 0xc0008324 (为何是0xc0008324而不是0x30008324???)
第4行算出虚、实地址的偏移,
第5-6行的结果应该是r5指向__arch_info_begin的实地址,r6指向__arch_info_end的实地址。
第7行读取__mach_desc_
SMDK2410结构中的nr参数到r3中,
第8行比较r3和r1中的机器编号是否相同,
r3中的nr值MACH_TYPE_SMDK2410定义在kernel\include\asm-arm\mach-types.h中:
#define MACH_TYPE_SMDK2410
193
r1中的值是由bootloader传递过来的,这在<<linux启动流程分析(1)---bootloader启动内核过程>>中有说明,如果机器编号相同,跳到14行返回。如果不同则将地址指针增加,在跳到7行继续查找,见10--12行的代码,如果检索完所有的machine_desc仍然没有找到则将r5清零并返回。
/*
* Lookup machine
architecture in the linker-build list of architectures.
* Note that we can't use
the absolute addresses for the __arch_info
* lists since we aren't
running with the MMU on (and therefore, we are
* not in the correct
address space). We have to calculate the
offset.
*
* r1 = machine architecture number
* Returns:
* r3, r4, r6 corrupted
* r5 = mach_info pointer in physical address
space
*/
.type __lookup_machine_type, %function
1: __lookup_machine_type:
2: adr r3,
3b
3: ldmia r3,
{r4, r5, r6}
4: sub r3,
r3, r4 @ get offset between
virt&phys
5: add r5,
r5, r3 @ convert virt addresses
to
6: add r6,
r6, r3 @ physical address space
7: 1: ldr r3,
[r5, #MACHINFO_TYPE] @ get machine type
8: teq r3,
r1 @ matches loader number?
9: beq 2f @
found
10: add r5,
r5, #SIZEOF_MACHINE_DESC @ next machine_desc
11: cmp r5,
r6
12: blo 1b
13: mov r5, #0 @
unknown machine
14 2: mov pc,
lr
posted @
2007-07-25 17:05 lfc 阅读(1294) |
评论 (0) |
编辑 收藏
注:
原文出自taoyuetao大侠的博客上:
http://www.eetop.cn/blog/html/45/11145_itemid_1396.html
小弟参考之研究s3c2410相关代码,然后做了稍微的修改,作为一个学习笔记,方便以后的学习,也希望对后人有所帮助^_^
前面一篇文章,简单介绍了内核启动的汇编主流程,这篇介绍其中调用的汇编子函数__lookup_processor_type
函数__lookup_processor_type介绍:
内核中使用了一个结构struct proc_info_list,用来记录处理器相关的信息,该结构定义在
kernel/include/asm-arm/procinfo.h头文件中。
/*
*
Note! struct processor is always defined
if we're
*
using MULTI_CPU, otherwise this entry is unused,
*
but still exists.
*
*
NOTE! The following structure is defined by assembly
*
language, NOT C code. For more
information, check:
*
arch/arm/mm/proc-*.S and arch/arm/kernel/head.S
*/
struct proc_info_list {
unsigned
int cpu_val;
unsigned
int cpu_mask;
unsigned
long __cpu_mmu_flags; /* used by head.S */
unsigned
long __cpu_flush; /* used by head.S */
const
char *arch_name;
const
char *elf_name;
unsigned
int elf_hwcap;
const
char *cpu_name;
struct
processor *proc;
struct
cpu_tlb_fns *tlb;
struct
cpu_user_fns *user;
struct
cpu_cache_fns *cache;
};
在arch/arm/mm/proc-arm920.S文件中定义了所有和arm920有关的proc_info_list,我们使用的arm920定义如下:
.section
".proc.info.init", #alloc, #execinstr
.type __arm920_proc_info,#object
__arm920_proc_info:
.long 0x41009200
.long 0xff00fff0
.
.
由于.section指示符,上面定义的__arm920_proc_info信息在编译的时候被放到了.proc.info段中,这是由linux的链接脚本文件arch/arm/kernel/vmlinux.lds指定的,参考如下:
SECTIONS
{
.
= TEXTADDR;
.init
: { /* Init code and data */
_stext
= .;
_sinittext
= .;
*(.init.text)
_einittext
= .;
__proc_info_begin
= .;
*(.proc.info.init)
__proc_info_end
= .;
.
.
这里的符号__proc_info_begin指向.proc.info的起始地址,而符号__proc_info_end指向.proc.info的结束地址。后面就会引用这两个符号,来指向.proc.info这个段。
下面来来看看函数的源代码,为了分析方便将函数按行进行编号,其中17-18行就是前面提到的对.proc.info的引用,
第2行将19行的地址放到寄存器r3中,adr是小范围的地址读取伪指令。
第3行将r3所指向的数据区的数据读出到r5,r6,r9,执行结果是
R5=__proc_info_begin,r6=__proc_info_end,r9=第19行的地址
用仿真器查看:
r5=0xc0018664
r6=0xc0018694
r9=0xc0008324(为何是0xc0008324而不是0x30008324???)
第4行算出虚、实地址的偏移,
第5-6行的结果应该是r5指向__proc_info_begin的实地址,r6指向__proc_info_end的实地址。
第7行读取cpu的id,这是一个协处理器指令,将processor ID存储在r9中。
第8行将r5指向的__arm920_proc_info开始的数据读出放到寄存器r3,r4,结果r3=0x41009200 (cpu_val),r4=0xff00fff0 (cpu_mask)。
第9-10行将读出的id和结构中的id进行比较,如果id相同则返回,返回时r9存储
processor ID,如果id不匹配,则将指针r10增加PROC_INFO_SZ (proc_info_list结构的长度,在这等于48),如果r5小于r6指定的地址,也就是
__proc_info_end,则继续循环比较下一个proc_info_list中的id,如第11-14行的代码,如果查找到__proc_info_end,仍未找到一个匹配的id,则将r5清零并返回,如15-16行,也就是说如果函数执行成功则r5指向匹配的proc_info_list结构地址,如果函数返回错误则r5为0。
/*
*
Read processor ID register (CP#15, CR0), and look up in the linker-built
*
supported processor list. Note that we
can't use the absolute addresses
*
for the __proc_info lists since we aren't running with the MMU on
*
(and therefore, we are not in the correct address space). We have to
*
calculate the offset.
*
*
Returns:
* r3, r4, r6 corrupted
* r5 = proc_info pointer in physical address
space
* r9 = cpuid
*/
.type __lookup_processor_type, %function
1 __lookup_processor_type:
2 adr r3,
3f
3 ldmda r3,
{r5, r6, r9}
4 sub r3,
r3, r9 @ get offset between
virt&phys
5 add r5,
r5, r3 @ convert virt addresses
to
6 add r6,
r6, r3 @ physical address space
7 mrc p15,
0, r9, c0, c0 @ get processor id
8 1: ldmia r5,
{r3, r4} @ value, mask
9 and r4,
r4, r9 @ mask wanted bits
10 teq r3,
r4
11 beq 2f
12 add r5,
r5, #PROC_INFO_SZ @
sizeof(proc_info_list)
13 cmp r5,
r6
14 blo 1b
15 mov r5,
#0 @ unknown processor
16 2: mov pc,
lr
/*
*
Look in include/asm-arm/procinfo.h and arch/arm/kernel/arch.[ch] for
*
more information about the __proc_info and __arch_info structures.
*/
17 .long __proc_info_begin
18 .long __proc_info_end
19 3: .long .
20 .long __arch_info_begin
21 .long __arch_info_end
posted @
2007-07-24 20:50 lfc 阅读(1567) |
评论 (0) |
编辑 收藏
USB
驱动移植心得
一、代码修改
主要是按照这个贴来做:
http://www.hfrk.net/S3C2410/kaifa/063152202483252_37.htm
我也看过其它不同版本的内核关于usb驱动的移植,移植方法几乎一样,只是修改的文件不同而已。上面的贴子有不少头文件没有例出来,以下是我按照以上贴子添加的代码(好像在很多论坛上包括头文件部分都显示不出来,在这里把include前面的#给删了,希望有帮助):
/*add by lfc*/
#include <asm/arch/regs-clock.h>
#include <asm/arch/usb-control.h>
#include <linux/device.h>
#include <linux/delay.h>
/*end add*/
/**********************add by lfc*************************************/
static struct s3c2410_hcd_info usb_sbc2410_info = {
.port[0] = {
.flags = S3C_HCDFLG_USED
}
};
int usb_sbc2410_init(void)
{
unsigned long upllvalue = (0x78<<12)|(0x02<<4)|(0x03);
printk("USB Control, (c) 2006 sbc2410\n");
s3c_device_usb.dev.platform_data = &usb_sbc2410_info;
while(upllvalue!=__raw_readl(S3C2410_UPLLCON))
{
__raw_writel(upllvalue,S3C2410_UPLLCON);
mdelay(1);
}
return 0;
}
/***************************end add**********************/
static void __init smdk2410_map_io(void)
{
s3c24xx_init_io(smdk2410_iodesc, ARRAY_SIZE(smdk2410_iodesc));
s3c24xx_init_clocks(0);
s3c24xx_init_uarts(smdk2410_uartcfgs, ARRAY_SIZE(smdk2410_uartcfgs));
s3c24xx_set_board(&smdk2410_board);
/*************************add by lfc****************************/
usb_sbc2410_init();
/*************************end add*******************************/
}
上面的修改其实也参考了这个牛贴一下,里面有大虾们对USB驱动移植的讨论,还不错:
http://www.linuxforum.net/forum/showflat.php?Cat=&Board=embedded&Number=556915&page=0&view=collapsed&sb=5&o=0&fpart=
其实到了这里,要修改的代码已经修改完了,比添加Nand flash的支持修改的地方还要少^_^,不过我一直以为还没修改好,最后发现原来是没配置好~_~
二、内核配置
下面说一下郁闷了我好一阵子的内核配置(支持USB)问题,这个就比Nand flash的配置要复杂多了。
1、让内核支持热插拔
│ General setup --->
│ │[*] Support for hot-pluggable devices
2、USB驱动设置,可能有些不选也行,不过没时间去试,至于为什么要选这些选项的话可以看一下这个贴(Linux下的硬件驱动——USB设备):
http://www-128.ibm.com/developerworks/cn/linux/l-usb/index1.html
│ │ Device Drivers --->
│ │ Generic Driver Options --->
│<*> Hotplug firmware loading support
│ │ Block devices --->
│ │ <*> Low Performance USB Block driver
│ │ SCSI device support --->
│ │ <*> SCSI generic support
│ │ [*] Probe all LUNs on each SCSI device
│ │ USB support --->
│ │<*> Support for Host-side USB
│ │[*] USB device filesystem
│ │<*> OHCI HCD support
│ │<*> USB Mass Storage support
│ │[*] USB Monitor
3、加入了MSDOS fs和VFAT fs的支持。
│ │ File systems --->
│ │ DOS/FAT/NT Filesystems --->
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ <*> MSDOS fs support │ │
│ │ <*> VFAT (Windows-95) fs support │ │
│ │ (936) Default codepage for FAT │ │
│ │ (cp936) Default iocharset for FAT │ │
│ │ < > NTFS file system support
做完这些后,插入u盘后,内核应该可以识别到u盘,出现:
usb 1-1: new full speed USB device using s3c2410-ohci and address 3
ub(1.3): GetMaxLUN returned 0, using 1 LUNs
但是,还有下面一句出错提示:
/dev/ub/a: unknown partition table
再次查看了贴子上大虾们的讨论,提到:“使能CONFIG_MSDOS_PARTITION选项”,再仔细查找,发现配置选项如下:
│ │ File systems --->
│ │ Partition Types --->
│ │ [*] PC BIOS (MSDOS partition tables) support
加上这个后应该就可以挂载usb上的MSDOS分区了
以下是我的内核插入u盘后的提示信息:
usb 1-1: new full speed USB device using s3c2410-ohci and 2
ub(1.2): GetMaxLUN returned 0, using 1 LUNs
/dev/ub/a: p1
表示usb设备已经挂载到/dev/ub/a/part1目录下
4.
加入中文字体库(可惜在我的板上还是没能正常显示中文~_~,知道的朋友麻烦告诉我一声,大家一起探讨)
│ │ Native Language Support --->
│ │<*> Simplified Chinese charset (CP936, GB2312)
│ │<*> NLS UTF8
以下是挂载usb设备后的显示:
[root@luofuchong /]# mount -t vfat -o iocharset=cp936 /dev/ub/a/part1 /mnt
[root@luofuchong /]# ls /mnt
cramfs-1.1.tar.gz netkit-base-0.17.tar.gz thttpd-2.25b.tar.gz
lfc settings.dat . . I. .. . .txt
三、一点心得。
1、如果想知道内核有没有识别出u盘的话可以执行命令:cat /proc/partitions ,看看插入USB前后分区信息有什么不同就知道了。
2、另外,如果想让内核把它当成SCSI设备来处理的话,只要把上面:
│ │ Device Drivers --->
│ │ Block devices --->
│ │ <*> Low Performance USB Block driver
的 Low Performance USB Block driver这个选项去掉,然后把:
│ │ Device Drivers --->
│ │ SCSI device support --->
│ │ <*>SCSI disk support
的SCSI disk support这个选项选上,重新编译内核就行。
注:
个人觉得使用usb设备的话Low Performance USB Block driver比SCSI disk要好,自己看着办吧^_^
3、最后,一般都会新建一个/dev/sda1的链接指向usb设备的挂载点的,可以在启动文件中使用命令ln -s xxx xxx来建立这个链接。
四、
呵呵,说了一大堆的废话,希望不要见怪。毕竟我对usb设备了解不多,如果有什么说错的地方请各位大虾见谅。其实关于usb驱动的移植在网上有不少的贴,我在这里只对针对我的经历作一点总结而已,希望能对大家有一点的帮助^_^
posted @
2007-01-24 13:21 lfc 阅读(7820) |
评论 (9) |
编辑 收藏
注:
u-boot
使用的是打上:
http://www.hhcn.com/cgi-bin/topic.cgi?forum=3&topic=651&show=0
上keety大侠提供的补丁生成的u-boot-1.1.3
这段时间不断有人问我u-boot启动内核的问题,记得在上次提供的u-boot源码中提到了go的方案,不过其实u-boot本来有一种更好的方案:
bootm
花了不少时间,查看了论坛上不少的帖子,认真阅读了bootm的源码,终于使用bootm把内核给跑起来了,
现把解决方法介绍如下:
一、在开始之前先说明一下bootm相关的东西。
1、首先说明一下,S3C2410架构下的bootm只对sdram中的内核镜像文件进行操作(好像AT91架构提供了一段从flash复制内核镜像的代码,不过针对s3c2410架构就没有这段代码,虽然可以在u-boot下添加这段代码,不过好像这个用处不大),所以请确保你的内核镜像下载到sdram中,或者在bootcmd下把flash中的内核镜像复制到sdram中。
2、-a参数后是内核的运行地址,-e参数后是入口地址。
3、
1)如果我们没用mkimage对内核进行处理的话,那直接把内核下载到0x30008000再运行就行,内核会自解压运行(不过内核运行需要一个tag来传递参数,而这个tag建议是由bootloader提供的,在u-boot下默认是由bootm命令建立的)。
2)如果使用mkimage生成内核镜像文件的话,会在内核的前头加上了64byte的信息,供建立tag之用。bootm命令会首先判断bootm xxxx 这个指定的地址xxxx是否与-a指定的加载地址相同。
(1)如果不同的话会从这个地址开始提取出这个64byte的头部,对其进行分析,然后把去掉头部的内核复制到-a指定的load地址中去运行之
(2)如果相同的话那就让其原封不同的放在那,但-e指定的入口地址会推后64byte,以跳过这64byte的头部。
二、好,接着介绍使用mkimage生成镜像文件并下载运行的方法。
方法一、
1、首先,用u-boot/tools/mkimage这个工具为你的内核加上u-boot引导所需要的文件头,具体做法如下:
[root@localhost tftpboot]#mkimage -n 'linux-2.6.14' -A arm -O linux -T kernel -C none -a 0x30008000 -e 0x30008000 -d zImage zImage.img
Image Name: linux-2.6.14
Created: Fri Jan 12 17:14:50 2007
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 1262504 Bytes = 1232.91 kB = 1.20 MB
Load Address: 0x30008000
Entry Point: 0x30008000
这里解释一下参数的意义:
-A ==> set architecture to 'arch'
-O ==> set operating system to 'os'
-T ==> set image type to 'type'
-C ==> set compression type 'comp'
-a ==> set load address to 'addr' (hex)
-e ==> set entry point to 'ep' (hex)
-n ==> set image name to 'name'
-d ==> use image data from 'datafile'
-x ==> set XIP (execute in place)
2
、下载内核
U-Boot 1.1.3 (Jan 12 2007 - 16:16:36)
U-Boot code: 33F80000 -> 33F9BAC0 BSS: -> 33F9FBAC
RAM Configuration:
Bank #0: 30000000 64 MB
Nor Flash: 512 kB
Nand Flash: 64 MB
In: serial
Out: serial
Err: serial
Hit any key to stop autoboot: 0
sbc2410=>tftp 0x31000000 zImage.img
TFTP from server 192.168.1.115; our IP address is 192.168.1.128
Filename 'zImage.img'.
Load address: 0x31000000
Loading: #################################################################
#################################################################
#################################################################
####################################################
done
Bytes transferred = 1263324 (1346dc hex)
3.运行
sbc2410=>bootm 0x31000000
## Booting image at 31000000 ...
Image Name: linun-2.6.14
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 1263260 Bytes = 1.2 MB
Load Address: 30008000
Entry Point: 30008000
Verifying Checksum ... OK
OK
Starting kernel ...
Uncompressing Linux.............................................................Linux version 2.6.14 (root@luofuchong) (gcc version 3.4.1) #21 Fri Oct 20 17:206CPU: ARM920Tid(wb) [41129200] revision 0 (ARMv4T)
Machine: SMDK2410
Memory policy: ECC disabled, Data cache writeback
CPU S3C2410A (id 0x32410002)
S3C2410: core 202.800 MHz, memory 101.400 MHz, peripheral 50.700 MHz
S3C2410 Clocks, (c) 2004 Simtec Electronics
CLOCK: Slow mode (1.500 MHz), fast, MPLL on, UPLL on
USB Control, (c) 2006 sbc2410
CPU0: D VIVT write-back cache
CPU0: I cache: 16384 bytes, associativity 64, 32 byte lines, 8 sets
CPU0: D cache: 16384 bytes, associativity 64, 32 byte lines, 8 sets
Built 1 zonelists
Kernel command line: console=ttySAC0 root=/dev/nfs nfsroot=192.168.1.115:/frien"irq: clearing subpending status 00000002
PID hash table entries: 512 (order: 9, 8192 bytes)
timer tcon=00500000, tcnt a509, tcfg 00000200,00000000, usec 00001e4c
Console: colour dummy device 80x30
Dentry cache hash table entries: 16384 (order: 4, 65536 bytes)
Inode-cache hash table entries: 8192 (order: 3, 32768 bytes)
Memory: 64MB = 64MB total
Memory: 62208KB available (1924K code, 529K data, 108K init)
Mount-cache hash table entries: 512
CPU: Testing write buffer coherency: ok
softlockup thread 0 started up.
NET: Registered protocol family 16
S3C2410: Initialising architecture
SCSI subsystem initialized
usbcore: registered new driver usbfs
usbcore: registered new driver hub
S3C2410 DMA Driver, (c) 2003-2004 Simtec Electronics
DMA channel 0 at c4800000, irq 33
DMA channel 1 at c4800040, irq 34
DMA channel 2 at c4800080, irq 35
DMA channel 3 at c48000c0, irq 36
NetWinder Floating Point Emulator V0.97 (double precision)
devfs: 2004-01-31 Richard Gooch (rgooch@atnf.csiro.au)
devfs: devfs_debug: 0x0
devfs: boot_options: 0x1
yaffs Oct 18 2006 12:39:51 Installing.
Console: switching to colour frame buffer device 30x40
fb0: s3c2410fb frame buffer device
fb1: Virtual frame buffer device, using 1024K of video memory
led driver initialized
s3c2410 buttons successfully loaded
s3c2410_serial0 at MMIO 0x50000000 (irq = 70) is a S3C2410
s3c2410_serial1 at MMIO 0x50004000 (irq = 73) is a S3C2410
s3c2410_serial2 at MMIO 0x50008000 (irq = 76) is a S3C2410
io scheduler noop registered
io scheduler anticipatory registered
io scheduler deadline registered
io scheduler cfq registered
RAMDISK driver initialized: 16 RAM disks of 4096K size 1024 blocksize
usbcore: registered new driver ub
Cirrus Logic CS8900A driver for Linux (Modified for SMDK2410)
eth0: CS8900A rev E at 0xe0000300 irq=53, no eeprom , addr: 08: 0:3E:26:0A:5B
S3C24XX NAND Driver, (c) 2004 Simtec Electronics
s3c2410-nand: mapped registers at c4980000
s3c2410-nand: timing: Tacls 10ns, Twrph0 30ns, Twrph1 10ns
NAND device: Manufacturer ID: 0xec, Chip ID: 0x76 (Samsung NAND 64MiB 3,3V 8-bi)Scanning device for bad blocks
Bad eraseblock 1884 at 0x01d70000
Creating 4 MTD partitions on "NAND 64MiB 3,3V 8-bit":
0x00000000-0x00020000 : "vivi"
0x00020000-0x00030000 : "param"
0x00030000-0x00200000 : "kernel"
0x00200000-0x04000000 : "root"
usbmon: debugfs is not available
s3c2410-ohci s3c2410-ohci: S3C24XX OHCI
s3c2410-ohci s3c2410-ohci: new USB bus registered, assigned bus number 1
s3c2410-ohci s3c2410-ohci: irq 42, io mem 0x49000000
hub 1-0:1.0: USB hub found
hub 1-0:1.0: 2 ports detected
Initializing USB Mass Storage driver...
usbcore: registered new driver usb-storage
USB Mass Storage support registered.
usbcore: registered new driver usbmouse
drivers/usb/input/usbmouse.c: v1.6:USB HID Boot Protocol mouse driver
mice: PS/2 mouse device common for all mice
s3c2410 TouchScreen successfully loaded
UDA1341 audio driver initialized
NET: Registered protocol family 2
IP route cache hash table entries: 1024 (order: 0, 4096 bytes)
TCP established hash table entries: 4096 (order: 2, 16384 bytes)
TCP bind hash table entries: 4096 (order: 2, 16384 bytes)
TCP: Hash tables configured (established 4096 bind 4096)
TCP reno registered
TCP bic registered
NET: Registered protocol family 1
IP-Config: Complete:
device=eth0, addr=192.168.1.128, mask=255.255.255.0, gw=192.168.1.1,
host=luofuchong, domain=, nis-domain=(none),
bootserver=192.168.1.1, rootserver=192.168.1.115, rootpath=
Looking up port of RPC 100003/2 on 192.168.1.115
Looking up port of RPC 100005/1 on 192.168.1.115
VFS: Mounted root (nfs filesystem).
Mounted devfs on /dev
Freeing init memory: 108K
init started: BusyBox v1.1.3 (2006.09.20-14:52+0000) multi-call binary
Starting pid 696, console /dev/tts/0: '/etc/init.d/rcS'
Please press Enter to activate this console.
方法二、
1、首先,用u-boot/tools/mkimage这个工具为你的内核加上u-boot引导所需要的文件头,具体做法如下:
[root@localhost tftpboot]#mkimage -n 'linux-2.6.14' -A arm -O linux -T kernel -C none -a 0x30008000 -e 0x30008040 -d zImage zImage.img
Image Name: linux-2.6.14
Created: Fri Jan 12 17:14:50 2007
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 1262504 Bytes = 1232.91 kB = 1.20 MB
Load Address: 0x30008000
Entry Point: 0x30008040
2
、下载内核
U-Boot 1.1.3 (Jan 12 2007 - 16:16:36)
U-Boot code: 33F80000 -> 33F9BAC0 BSS: -> 33F9FBAC
RAM Configuration:
Bank #0: 30000000 64 MB
Nor Flash: 512 kB
Nand Flash: 64 MB
In: serial
Out: serial
Err: serial
Hit any key to stop autoboot: 0
sbc2410=>tftp 0x30008000 zImage.img
TFTP from server 192.168.1.115; our IP address is 192.168.1.128
Filename 'zImage.img'.
Load address: 0x30008000
Loading: #################################################################
#################################################################
#################################################################
####################################################
done
Bytes transferred = 1263324 (1346dc hex)
3.运行
sbc2410=>bootm 0x30008000
## Booting image at 30008000 ...
Image Name: linux-2.6.14
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 1261056 Bytes = 1.2 MB
Load Address: 30008000
Entry Point: 30008040
Verifying Checksum ... OK
XIP Kernel Image ... OK
内核启动信息省。。。。
三、固化
如果你想把镜像文件写入flash,每次开机后让u-boot帮你复制到sdram中,再使用bootm命令引导的话,可以按照这样操作:
sbc2410=>tftp 0x30008000 zImage.img
TFTP from server 192.168.1.115; our IP address is 192.168.1.128
Filename 'zImage.img'.
Load address: 0x30008000
Loading: #################################################################
#################################################################
#################################################################
####################################################
done
Bytes transferred = 1263324 (1346dc hex)
sbc2410=>nand erase 0x30000 0x1d0000
NAND erase: device 0 offset 196608, size 1900544 ... OK
sbc2410=>nand write 0x30008000 0x30000 0x1d0000
NAND write: device 0 offset 196608, size 1900544 ... 1900544 bytes written: OK
设置u-boot启动命令:
1、针对方法一:
sbc2410=>setenv bootcmd nand read 0x31000000 0x30000 0x1d0000\;bootm 0x31000000
sbc2410=>saveenv
Saving Environment to NAND...
Erasing Nand...Writing to Nand... done
2、针对方法二:
sbc2410=>setenv bootcmd nand read 0x30008000 0x30000 0x1d0000\;bootm 0x30008000
sbc2410=>saveenv
Saving Environment to NAND...
Erasing Nand...Writing to Nand... done
sbc2410=>reset
启动信息略。。。。
posted @
2007-01-12 23:13 lfc 阅读(47990) |
评论 (10) |
编辑 收藏
摘要: 几经艰辛,终于基本完成了
u-boot
在
s3c44b0
的移植工作,在些记录一下在移植过程中所碰到的困难和解决方法(一些心得),作为日后参考之用,也希望能够帮到其它有需要的人
^_^
。
1.
...
阅读全文
posted @
2007-01-10 15:41 lfc 阅读(7980) |
评论 (15) |
编辑 收藏
摘要: 2.6.14 内核移植说明文档
一、编译内核
1. make distclean 或者 make mrproper
如果你是新下载的内核,那这一步就不用了。但如果你用的是别人移植好的内核,那最好在编译内核之前先清除一下中间文件,因为你们用来编译内核的交叉编译工具可能不同。
2.修改 Makefile
主要是以下两项:
1 ) ARCH = arm
2) CROSS_CO...
阅读全文
posted @
2007-01-10 15:35 lfc 阅读(19317) |
评论 (17) |
编辑 收藏
文件系统的制作
前言
:
文件系统的制作其实并没有想像中那么难。一个基本的文件系统应该包括:
busybox
(提供
shell
命令集)、配置文件(用来初始化和布局你的文件系统)、设备文件(如果是用
devfs
的话这个就免了)、必要的库文件系统(如果
busybox
是静态编译的话,那根本不用为
busybox
用到的库文件而烦。在我制作的文件系统里,只是为了用户程序和
qt
的运行才放置了一些库文件)。
正文
:
一、
首先说一下
busybox
的配置和编译问题
其实搞好
busybox
后,可以说你的文件系统已经完成了一半了。
Busybox
之所以比较难编译,主要是
busybox
和交叉编译工具的版本搭配问题。在文坛上不乏因为
busybox
某些命令不能编译通过而烦的人,在这里我推荐一个搭配:
busybox-1.1.3+arm-linux-gcc-3.3.2
(在文坛上看到过有人说
busybox-1.0.1+arm-linux-gcc-3.4.1
也可以正常编译通过,你自己看着办吧)。
Busybox
的配置很简单,详细过程可以参考《基于
S3C2410
的
Linux
全线移植文档》的文件系统部分,我刚开始的时候就是按照这个来做出一个很简单的文件系统的。
不过有一点要特别注意的
(shell
的配置问题
)
:
1、要这样配置:
│ │
Shells --->
│ Choose your default shell (ash) --->
2、如果是这样配置的话,虽然可以生成ash,但不能生成sh:
│ │ Choose your default shell (none) ---> │ │
│ │ [*] ash
另外,按照他的这种方法做出来的文件系统,运行的时候
shell
并不好有,没有历史记录、自动补全、删除字符的功能,下面介绍如何为它添加这些功能:
Shells --->
--- Bourne Shell Options
│
│
[ ] Hide message on interactive shell startup
│
│
[ ] Standalone shell
│
│
[*] command line editing
│
│
[*] vi-style line editing commands
│
│
(15) history size
│
│
[*] history saving
│
│
[*] tab completion
│
│
[*] username completion
│
│
[ ] Fancy shell prompts
这是我自己试验出来的,网上没有看到过这方面的介绍,在此奉献给大家。
二、
再来说一下配置文件的问题
在文件系统中,配置文件主要存放在
/etc
目录里面。《基于
S3C2410
的
Linux
全线移植文档》里面介绍的文件系统由于需要加载文件系统的时候把
/mnt/etc
目录拷贝到
/etc
,所以不得不使用
/linuxrc
脚本,不过如果是这样的话需要在内核传递参数里设置
init=/linuxrc
,因为默认是启动
/sbin/init
初始化脚本的(
busybox
编译安装以后生成的
linuxrc
文件是指向
/bin/busybox
的符号文件,应该把它删掉,自己重写脚本)。在我做的文件系统里不采用这种方法,所以不用设置
init=/linuxrc
。
Busybox init
的流程在《构建嵌入式
linux
系统》这本书里面有介绍,我在这简单的说一下:如果不采用
linuxrc
的话就会执行
/sbin/init
脚本(
busybox init
),它会去分析
/etc/inittab
脚本(如果没有的话就使用它默认的来代替,一般没必要自己为它编写这个脚本,用它默认的就行),然后会执行
/etc/init.d/rcS
命令(在我制作的文件系统里就把配置都写入了这个文件)。
至于
rcS
这个目录的编写主要是安排哪些目录挂载哪些次级文件系统,比如
/proc
要挂载
proc
文件系统、
/sys
要挂载
sysfs
、
/dev/shm
要挂载
tmpfs
、
/tmp
要挂载
ramfs
等等。此外,还可以让内核重新挂载根文件系统也行,具体可以参考
rcS
这个脚本里面的内容,我的是参考友善的那个来写的。另外,可以在这个脚本里执行一些命令,比如设置
ip
地址、建立符号链接(我为
usb
设备的挂载特意建立了
/dev/sda1
的符号链接)、设置主机名等等。
Busybox init
还会调用
/etc/profile
来设置
PATH
,具体请看文件。
在《构建嵌入式
linux
系统》提到了怎样建立和建立哪些设备文件,但因为
devfs
这个东西的存在,我们可以不再为这些设备文件而费心了。因为内核在申请设备的同时会向
devfs
申请相应的设备文件,然后
devfs
会帮我们在
/dev
目录建立相应的设备文件,做到内核使用多少设备就建立多少设备文件,不像以前那样要预先建立一大堆可以你不会用到的设备文件(不过从
2.6.12
内核开始,这个
devfs
选项从内核配置中删除,好像是用
udevfs
之类来代替了,不过很多人还是喜欢用回
devfs
,而且按现在看来起码它用得还挺不错的)。
好像没什么好讲了,至于
/lib
目录应该放哪些库文件,我也没有底。如果不运行应用程序,只是运行
busybox
的话根本不用放任何的库,因为我们的
busybox
是静态链接的还记得吧?我在自己的文件系统中存放了
helloworld
应用程序和模块,另外还有一个
led
模块,是用
ioctl
来控制
led
灯的亮和灭的,所以我才加载了一些库,而且是从原来友善的文件系统里面拷过来的。以后如果要运行
qt
的话,还要把
qt
用到的库文件也放进去,这样文件系统就变得挺大的了。
总结
:
好了,一个简单的文件系统就是如此简单的就可以做出来。不过要做出一个合理的文件系统的话相信还有很多东西要注意,比如根文件系统各目录应该使用什么次级文件系统、配置文件的设计、选用哪些库文件、如何增加用户管理和网络功能
(boa)
等等。网上关于文件系统制作的介绍很少,不过有个不错的方法就是参考人家文件系统的做法来做,我就是参考友善文件系统的做法来做的。在这里提供一个下载文件系统的好地方,里面有很多的文件系统可以给你参考:
http://husaberg.toby-churchill.com/balloon/releases/v0.7/roots/
。
好了,总结如此,希望对你有帮助。
posted @
2007-01-10 11:09 lfc 阅读(17002) |
评论 (11) |
编辑 收藏