基于tiny4412的Linux内核移植(支持device tree)(三)
2016-03-22 17:03
603 查看
转自:http://www.cnblogs.com/pengdonglin137/p/5146791.html
阅读目录(Content)
作者信息
平台简介
注意
一、设备树反编译
二、在u-boot打印信息
三、打开Linux内核启动早期的log
四、在内核自解压时dump内存
五、CONFIG_ARM_APPENDED_DTB
回到顶部(gototop)
作者:彭东林
邮箱:pengdonglin137@163.com
QQ:405728433
回到顶部(gototop)
开发板:tiny4412ADK+S700+4GBFlash
要移植的内核版本:Linux-4.4.0(支持devicetree)
u-boot版本:友善之臂自带的U-Boot2010.12(为支持uImage启动,做了少许改动)
busybox版本:busybox1.25
交叉编译工具链:arm-none-linux-gnueabi-gcc
(gccversion4.8.320140320(prerelease)(SourceryCodeBenchLite2014.05-29))
回到顶部(gototop)
继续上文。
到目前为止,板子已经可以起来了,接下来就可以针对板子的情况移植驱动程序了。这个放在以后再做,下面是我折腾过程中得到的一些知识,分享一下。
在内核目录下当我们执行makedtbs后,就会在arch/arm/boot/dts下生成一些.dtb文件,那这个文件里是什么东西呢?我们可以用dtc命令反编译这些dtb文件,下面以exynos4412-tiny4412.dtb为例:
命令:
然后就会生成反编译后的文件tiny4412.dts,部分内容如下:
这个方法对于学习设备树很有帮助。
在u-boot中很多文件中是通过debug(……)来打印信息,默认情况下这些log是打印不出来的。这个函数的定义是在include/common.h中:
#ifdefDEBUG
#definedebug(fmt,args...)printf(fmt,##args)
#definedebugX(level,fmt,args...)if(DEBUG>=level)printf(fmt,##args);
#else
#definedebug(fmt,args...)
#definedebugX(level,fmt,args...)
#endif/*DEBUG*/
所以可以在调用debug函数的C文件的最上面添加#defineDEBUG即可。这个方法在Linux内核以及Android当中也很常用。
有时会遇到当在u-boot中执行完bootm后,打印出startkernel后串口就没有再输出任何信息了。此时就需要打开内核早期的log:
makemenuconfig
Kernelhacking--->
[*]Kernellow-leveldebuggingfunctions(readhelp!)
Kernellow-leveldebuggingport(UseSamsungS3CUART0forlow-leveldebug)
[*]Earlyprintk
对于earlyprintk,还需要在bootargs中添加参数earlyprintk才能生效,有了上面这几个配置,会有下面几个宏生效:
CONFIG_DEBUG_LL=y
CONFIG_DEBUG_S3C_UART0=y
CONFIG_DEBUG_LL_INCLUDE="debug/exynos.S"
CONFIG_DEBUG_UNCOMPRESS=y
CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
CONFIG_EARLY_PRINTK=y
关于earlyprintk的解析在文件arch/arm/kernel/early_printk.c中:
其中printch都是通过汇编语言实现的。
在arch/arm/Kconfig.debug中可以看到:
configDEBUG_LL
bool"Kernellow-leveldebuggingfunctions(readhelp!)"
dependsonDEBUG_KERNEL
help
SayYheretoincludedefinitionsofprintascii,printch,printhex
inthekernel.Thisishelpfulifyouaredebuggingcodethat
executesbeforetheconsoleisinitialized.
configDEBUG_S3C_UART0
dependsonPLAT_SAMSUNG
selectDEBUG_EXYNOS_UARTifARCH_EXYNOS
selectDEBUG_S3C24XX_UARTifARCH_S3C24XX
selectDEBUG_S5PV210_UARTifARCH_S5PV210
bool"UseSamsungS3CUART0forlow-leveldebug"
help
SayYhereifyouwantthedebugprintroutinestodirect
theiroutputtoUART0.Theportmusthavebeeninitialised
bytheboot-loaderbeforeuse.
configDEBUG_LL_INCLUDE
string
……
default"debug/exynos.S"ifDEBUG_EXYNOS_UART
configEARLY_PRINTK
bool"Earlyprintk"
dependsonDEBUG_LL
help
SayYhereifyouwanttohaveanearlyconsoleusingthe
kernellow-leveldebuggingfunctions.Addearlyprintktoyour
kernelparameterstoenablethisconsole.
从上面的信息我们可以知道:
在串口终端尚未注册时,内核定义了printascii、printch以及printhex用于调试;
earlyconsole使用的也是上面定义的函数,需要在传递给内核的参数中添加earlyprintk参数
Linux内核早期的print函数的输出串口要跟u-boot下使用的一致,即内核不再负责初始化了,让u-boot来做,所以二者一定要一致,否则那些print函数以及earlyprintk都没法输出信息;
可以参考arch/arm/kernel/debug.S,printascii、printch以及printhex都是在这里定义的;
在kernel进入C函数(start_kernel)后可以调用early_print来打印信息,它是在arch/arm/kernel/setup.c中定义的:
可以看到,early_print也会调用printascii和printk,意思是用early_print打印的信息可能会重复出现在终端上(printk会缓冲一部分,当bootconsole注册后,会将printk缓冲区中的内容输出)。
上面所说的打印函数只能在内核自解压后的函数中才能使用,那么内核自解压过程中的信息是不是也可以打印呢?可以,内核自解压相关的文件在arch/arm/boot/compressed/下面,我们所熟知的:
UncompressingLinux...done,bootingthekernel.
就是这个目录下的代码打印出来的,具体代码如下:
arch/arm/boot/compressed/misc.c
其中,putstr的定义如下:
putc是汇编实现的,arch/arm/boot/compressed/debug.S:
其中addruart的实现因soc的不同而不同,对于exynos4412,它的实现是(arch/arm/include/debug/exynos.S):
这个函数的目的就是获得控制调试uart的寄存器的物理基地址(rp)和虚拟基地址(rv),这里也没有初始化uart的代码,所以必须跟u-boot使用的串口一致。
这是在调试设备树在内存中的镜像被自解压后的内核覆盖时发现的。下面是使用方法:
首先需要按照上面的一节配置内核打开那几个宏
修改arch/arm/boot/compressed/head.S,如下:
可以使用kputc打印出一个字符,kphex用于打印一个指定位宽的十六进制数,将需要dump的内粗地址存放入r0,然后调用memdump即可,memdump会dump出256B的内容。u-boot在跳转到内核的时候传递三个参数,分别给了r0、r1、r2,在没有设备树之前,传给r0,r1和r2的分别是0,machid以及u-boot传给Linux内核参数的地址(如0x40000100),在有了设备树之后,传给r0的是0,传给r1的值无所谓,传给r2的是设备树镜像在内存中的地址。效果如下:
可以看到UncompressingLinux...done,bootingthekernel.前后就是dump出的设备树的内容(大小端可能有些问题).
这个宏是Linux内核中的,它的作用是支持zImage+dtb的启动方式。为什么要有种方式呢?因为很多厂家都有自己的bootloader,但是这些bootloader并不都一定支持设备树,为了实现支持设备树启动,就引入了这种启动方式,即将编译出的zImage和编译出的设备树镜像文件拼成一个新的镜像,在内核的自解压代码中会识别到,不会出现自解压时导致设备树被覆盖,具体实现如下(arch/arm/boot/compressed/head.S)
拼接方法:
也可以修改内核编译系统,在编译完成后自动实现拼接,可以参考下面的博文实现:
/article/5055154.html
下面是使用dtbImage启动的方法:
1、修改设备树arch/arm/boot/dts/exynos4412-tiny4412.dts
2、编译设备树makedtbs,将生成的.dtb跟zImag拼接起来生成dtbImage
3、使用ramdisk启动,目前不能使用ramdisk.img,还不知道为什么。
4、启动开发板,进入u-boot命令行模式,执行如下命令:
在u-boot里执行下载dtbImage的命令:dnw0x40008000
在开发机上执行:dnwdtbImage
在u-boot里执行下载ramdisk的命令:dnw0x41000000
在开发机上执行:dnwramdisk
启动内核:bootm0x40008000(u-boot不识别未压缩的ramdisk,ramdisk的地址在bootargs中指定为0x41000000,而且上面我们已经把ramdisk下载到0x41000000了)
下面是完整的log:
阅读目录(Content)
作者信息
作者:彭东林邮箱:
QQ:405728433
平台简介
开发板:tiny4412ADK+S700+4GBFlash要移植的内核版本:Linux-4.4.0(支持devicetree)
u-boot版本:友善之臂自带的U-Boot2010.12(为支持uImage启动,做了少许改动)
busybox版本:busybox1.25
交叉编译工具链:arm-none-linux-gnueabi-gcc
(gccversion4.8.320140320(prerelease)(SourceryCodeBenchLite2014.05-29))
注意
继续上文。到目前为止,板子已经可以起来了,接下来就可以针对板子的情况移植驱动程序了。这个放在以后再做,下面是我折腾过程中得到的一些知识,分享一下。
一、设备树反编译
在内核目录下当我们执行makedtbs后,就会在arch/arm/boot/dts下生成一些.dtb文件,那这个文件里是什么东西呢?我们可以用dtc命令反编译这些dtb文件,下面以exynos4412-tiny4412.dtb为例:命令:
dtc-Idtb-Odtb-otiny4412.dtsarch/arm/boot/dts/exynos4412-tiny4412.dtb
然后就会生成反编译后的文件tiny4412.dts,部分内容如下:
/dts-v1/; /{ #address-cells=<;0x1>; #size-cells=<;0x1>; interrupt-parent=<;0x1>; compatible="friendlyarm,tiny4412","samsung,exynos4412","samsung,exynos4"; model="FriendlyARMTINY4412boardbasedonExynos4412"; chosen{ stdout-path="/serial@13800000"; bootargs="root=/dev/ram0rwrootfstype=ext4console=ttySAC0,115200init=/linuxrcearlyprintk"; }; aliases{ spi0="/spi@13920000"; spi1="/spi@13930000"; spi2="/spi@13940000"; i2c0="/i2c@13860000"; i2c1="/i2c@13870000"; i2c2="/i2c@13880000"; i2c3="/i2c@13890000"; i2c4="/i2c@138A0000"; i2c5="/i2c@138B0000"; i2c6="/i2c@138C0000"; i2c7="/i2c@138D0000"; i2c8="/i2c@138E0000"; csis0="/camera/csis@11880000"; csis1="/camera/csis@11890000"; fimc0="/camera/fimc@11800000"; fimc1="/camera/fimc@11810000"; fimc2="/camera/fimc@11820000"; fimc3="/camera/fimc@11830000"; serial0="/serial@13800000"; serial1="/serial@13810000"; serial2="/serial@13820000"; serial3="/serial@13830000"; pinctrl0="/pinctrl@11400000"; pinctrl1="/pinctrl@11000000"; pinctrl2="/pinctrl@03860000"; pinctrl3="/pinctrl@106E0000"; fimc-lite0="/camera/fimc-lite@12390000"; fimc-lite1="/camera/fimc-lite@123A0000"; mshc0="/mmc@12550000"; }; memory{ device_type="memory"; reg=<0x400000000x40000000>; }; clock-controller@03810000{ compatible="samsung,exynos4210-audss-clock"; reg=<0x38100000xc>; #clock-cells=<;0x1>; linux,phandle=<;0x2>; phandle=<;0x2>; }; i2s@03830000{
这个方法对于学习设备树很有帮助。
二、在u-boot打印信息
在u-boot中很多文件中是通过debug(……)来打印信息,默认情况下这些log是打印不出来的。这个函数的定义是在include/common.h中:#ifdefDEBUG
#definedebug(fmt,args...)printf(fmt,##args)
#definedebugX(level,fmt,args...)if(DEBUG>=level)printf(fmt,##args);
#else
#definedebug(fmt,args...)
#definedebugX(level,fmt,args...)
#endif/*DEBUG*/
所以可以在调用debug函数的C文件的最上面添加#defineDEBUG即可。这个方法在Linux内核以及Android当中也很常用。
三、打开Linux内核启动早期的log
有时会遇到当在u-boot中执行完bootm后,打印出startkernel后串口就没有再输出任何信息了。此时就需要打开内核早期的log:makemenuconfig
Kernelhacking--->
[*]Kernellow-leveldebuggingfunctions(readhelp!)
Kernellow-leveldebuggingport(UseSamsungS3CUART0forlow-leveldebug)
[*]Earlyprintk
对于earlyprintk,还需要在bootargs中添加参数earlyprintk才能生效,有了上面这几个配置,会有下面几个宏生效:
CONFIG_DEBUG_LL=y
CONFIG_DEBUG_S3C_UART0=y
CONFIG_DEBUG_LL_INCLUDE="debug/exynos.S"
CONFIG_DEBUG_UNCOMPRESS=y
CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
CONFIG_EARLY_PRINTK=y
关于earlyprintk的解析在文件arch/arm/kernel/early_printk.c中:
1:externvoidprintch(int);
2:
3:staticvoidearly_write(constchar*s,unsignedn)
4:{
5:while(n-->;0){
6:if(*s=='\n')
7:printch('\r');
8:printch(*s);
9:s++;
10:}
11:}
12:
13:staticvoidearly_console_write(structconsole*con,constchar*s,unsignedn)
14:{
15:early_write(s,n);
16:}
17:
18:staticstructconsoleearly_console_dev={
19:.name="earlycon",
20:.write=early_console_write,
21:.flags=CON_PRINTBUFFER|CON_BOOT,
22:.index=-1,
23:};
24:
25:staticint__initsetup_early_printk(char*buf)
26:{
27:early_console=&;early_console_dev;
28:register_console(&;early_console_dev);
29:return0;
30:}
31:
32:early_param("earlyprintk",setup_early_printk);
其中printch都是通过汇编语言实现的。
在arch/arm/Kconfig.debug中可以看到:
configDEBUG_LL
bool"Kernellow-leveldebuggingfunctions(readhelp!)"
dependsonDEBUG_KERNEL
help
SayYheretoincludedefinitionsofprintascii,printch,printhex
inthekernel.Thisishelpfulifyouaredebuggingcodethat
executesbeforetheconsoleisinitialized.
configDEBUG_S3C_UART0
dependsonPLAT_SAMSUNG
selectDEBUG_EXYNOS_UARTifARCH_EXYNOS
selectDEBUG_S3C24XX_UARTifARCH_S3C24XX
selectDEBUG_S5PV210_UARTifARCH_S5PV210
bool"UseSamsungS3CUART0forlow-leveldebug"
help
SayYhereifyouwantthedebugprintroutinestodirect
theiroutputtoUART0.Theportmusthavebeeninitialised
bytheboot-loaderbeforeuse.
configDEBUG_LL_INCLUDE
string
……
default"debug/exynos.S"ifDEBUG_EXYNOS_UART
configEARLY_PRINTK
bool"Earlyprintk"
dependsonDEBUG_LL
help
SayYhereifyouwanttohaveanearlyconsoleusingthe
kernellow-leveldebuggingfunctions.Addearlyprintktoyour
kernelparameterstoenablethisconsole.
从上面的信息我们可以知道:
在串口终端尚未注册时,内核定义了printascii、printch以及printhex用于调试;
earlyconsole使用的也是上面定义的函数,需要在传递给内核的参数中添加earlyprintk参数
Linux内核早期的print函数的输出串口要跟u-boot下使用的一致,即内核不再负责初始化了,让u-boot来做,所以二者一定要一致,否则那些print函数以及earlyprintk都没法输出信息;
可以参考arch/arm/kernel/debug.S,printascii、printch以及printhex都是在这里定义的;
在kernel进入C函数(start_kernel)后可以调用early_print来打印信息,它是在arch/arm/kernel/setup.c中定义的:
1:void__initearly_print(constchar*str,...)
2:{
3:externvoidprintascii(constchar*);
4:charbuf[256];
5:va_listap;
6:
7:va_start(ap,str);
8:vsnprintf(buf,sizeof(buf),str,ap);
9:va_end(ap);
10:
11:#ifdefCONFIG_DEBUG_LL
12:printascii(buf);
13:#endif
14:printk("%s",buf);
15:}
可以看到,early_print也会调用printascii和printk,意思是用early_print打印的信息可能会重复出现在终端上(printk会缓冲一部分,当bootconsole注册后,会将printk缓冲区中的内容输出)。
上面所说的打印函数只能在内核自解压后的函数中才能使用,那么内核自解压过程中的信息是不是也可以打印呢?可以,内核自解压相关的文件在arch/arm/boot/compressed/下面,我们所熟知的:
UncompressingLinux...done,bootingthekernel.
就是这个目录下的代码打印出来的,具体代码如下:
arch/arm/boot/compressed/misc.c
1:void
2:decompress_kernel(unsignedlongoutput_start,unsignedlongfree_mem_ptr_p,
3:unsignedlongfree_mem_ptr_end_p,
4:intarch_id)
5:{
6:......
7:putstr("UncompressingLinux...");
8:ret=do_decompress(input_data,input_data_end-input_data,
9:output_data,error);
10:......
11:putstr("done,bootingthekernel.\n");
12:}
其中,putstr的定义如下:
1:staticvoidputstr(constchar*ptr)
2:{
3:charc;
4:
5:while((c=*ptr++)!='\0'){
6:if(c=='\n')
7:putc('\r');
8:putc(c);
9:}
10:
11:flush();
12:}
putc是汇编实现的,arch/arm/boot/compressed/debug.S:
1:#includeCONFIG_DEBUG_LL_INCLUDE
2:
3:ENTRY(putc)
4:addruartr1,r2,r3
5:waituartr3,r1
6:senduartr0,r1
7:busyuartr3,r1
8:movpc,lr
9:ENDPROC(putc)
10:
11:
其中addruart的实现因soc的不同而不同,对于exynos4412,它的实现是(arch/arm/include/debug/exynos.S):
1:.macroaddruart,rp,rv,tmp
2:mrcp15,0,\tmp,c0,c0,0
3:and\tmp,\tmp,#0xf0
4:teq\tmp,#0xf0@@A15
5:ldreq\rp,=EXYNOS5_PA_UART
6:movne\rp,#EXYNOS4_PA_UART@@EXYNOS4
7:ldr\rv,=S3C_VA_UART
8:CONFIG_DEBUG_S3C_UART!=0
9:add\rp,\rp,#(0x10000*CONFIG_DEBUG_S3C_UART)
10:add\rv,\rv,#(0x10000*CONFIG_DEBUG_S3C_UART)
11:if
12:.endm
这个函数的目的就是获得控制调试uart的寄存器的物理基地址(rp)和虚拟基地址(rv),这里也没有初始化uart的代码,所以必须跟u-boot使用的串口一致。
四、在内核自解压时dump内存
这是在调试设备树在内存中的镜像被自解压后的内核覆盖时发现的。下面是使用方法:首先需要按照上面的一节配置内核打开那几个宏
修改arch/arm/boot/compressed/head.S,如下:
1:diff--gita/arch/arm/boot/compressed/head.Sb/arch/arm/boot/compressed/head.S
2:index06e983f..7ecde2e100644
3:---a/arch/arm/boot/compressed/head.S
4:+++b/arch/arm/boot/compressed/head.S
5:@@-22,6+22,8@@
6:*100%relocatable.Anyattempttodosowillresultinacrash.
7:*Pleaseselectoneofthefollowingwhenturningondebugging.
8:*/
9:+#defineDEBUG
10:+
11:#ifdefDEBUG
12:
13:#ifdefined(CONFIG_DEBUG_ICEDCC)
14:@@-65,7+67,7@@
15:.endm
16:#else
17:.macroloadsp,rb,tmp
18:-addruart\rb,\tmp
19:+addruart\rb,\tmp,\tmp
20:.endm
21:#endif
22:#endif
23:@@-536,6+538,24@@not_relocated:movr0,#0
24:*r7=architectureID
25:*r8=atagspointer
26:*/
27:+stmfdsp!,{r0-r3,r10-r12,lr}
28:+kputc#'\n'
29:+kputc#'a'
30:+kputc#'t'
31:+kputc#'a'
32:+kputc#'g'
33:+kputc#'s'
34:+kputc#':'
35:+kputc#''
36:+kputc#'0'
37:+kputc#'x'
38:+kphexr8,8/*atagspointer*/
39:+kputc#'\n'
40:+movr0,r8
41:+blmemdump/*dump256bytesatstartofkernel*/
42:+kputc#'\n'
43:+ldmfdsp!,{r0-r3,r10-r12,lr}
44:+
45:movr0,r4
46:movr1,sp@mallocspaceabovestack
47:addr2,sp,#0x10000@64kmax
48:@@-546,6+566,26@@not_relocated:movr0,#0
49:movr1,r7@restorearchitecturenumber
50:movr2,r8@restoreatagspointer
51:
52:+stmfdsp!,{r0-r3,r10-r12,lr}
53:+kputc#'\n'
54:+kputc#'\n'
55:+kputc#'a'
56:+kputc#'t'
57:+kputc#'a'
58:+kputc#'g'
59:+kputc#'s'
60:+kputc#':'
61:+kputc#''
62:+kputc#'0'
63:+kputc#'x'
64:+kphexr8,8/*atagspointer*/
65:+kputc#'\n'
66:+movr0,r8
67:+blmemdump/*dump256bytesatstartofkernel*/
68:+kputc#'\n'
69:+ldmfdsp!,{r0-r3,r10-r12,lr}
70:+
71:+
72:#ifdefCONFIG_ARM_VIRT_EXT
73:mrsr0,spsr@GetsavedCPUbootmode
74:andr0,r0,#MODE_MASK
可以使用kputc打印出一个字符,kphex用于打印一个指定位宽的十六进制数,将需要dump的内粗地址存放入r0,然后调用memdump即可,memdump会dump出256B的内容。u-boot在跳转到内核的时候传递三个参数,分别给了r0、r1、r2,在没有设备树之前,传给r0,r1和r2的分别是0,machid以及u-boot传给Linux内核参数的地址(如0x40000100),在有了设备树之后,传给r0的是0,传给r1的值无所谓,传给r2的是设备树镜像在内存中的地址。效果如下:
U-Boot2010.12-00000-gb391276-dirty(Jan172016-06:03:22)forTINY4412
CPU:S5PC220[SamsungSOConSMPPlatformBaseonARMCortexA9]
APLL=1400MHz,MPLL=800MHz
Board:TINY4412
DRAM:1023MiB
vdd_arm:1.2
vdd_int:1.0
vdd_mif:1.1
BL1version:N/A(TrustZoneEnabledBSP)
CheckingBootMode...SDMMC
REVISION:1.1
MMCDevice0:3803MB
MMCDevice1:3728MB
MMCDevice2:N/A
***Warning-usingdefaultenvironment
Net:Noethernetfound.
Hitanykeytostopautoboot:0
TINY4412#
TINY4412#dnw0x40000000
OTGcableConnected!
Now,WaitingforDNWtotransmitdata
DownloadDone!!DownloadAddress:0x40000000,DownloadFilesize:0x43bde8
Checksumisbeingcalculated.....
ChecksumO.K.
TINY4412#dnw0x41000000
OTGcableConnected!
Now,WaitingforDNWtotransmitdata
DownloadDone!!DownloadAddress:0x41000000,DownloadFilesize:0x27752e
Checksumisbeingcalculated...
ChecksumO.K.
TINY4412#dnw0x42000000
OTGcableConnected!
Now,WaitingforDNWtotransmitdata
DownloadDone!!DownloadAddress:0x42000000,DownloadFilesize:0xa53a
Checksumisbeingcalculated.
ChecksumO.K.
TINY4412#bootm0x400000000x410000000x42000000
##BootingkernelfromLegacyImageat40000000...
ImageName:Linux-4.4.0-gbd49c0f-dirty
ImageType:ARMLinuxKernelImage(uncompressed)
DataSize:4439464Bytes=4335KiB
LoadAddress:40008000
EntryPoint:40008000
VerifyingChecksum...OK
##LoadinginitRamdiskfromLegacyImageat41000000...
ImageName:ramdisk
ImageType:ARMLinuxRAMDiskImage(gzipcompressed)
DataSize:2585838Bytes=2525KiB
LoadAddress:00000000
EntryPoint:00000000
VerifyingChecksum...OK
##FlattenedDeviceTreeblobat42000000
Bootingusingthefdtblobat0x42000000
LoadingKernelImage...OK
OK
##LoadinginitRamdiskfromLegacyImageat41000000...
ImageName:ramdisk
ImageType:ARMLinuxRAMDiskImage(gzipcompressed)
DataSize:2585838Bytes=2525KiB
LoadAddress:00000000
EntryPoint:00000000
VerifyingChecksum...OK
LoadingRamdiskto43a84000,end43cfb4ee...OK
LoadingDeviceTreeto413f2000,end413ff539...OK
Startingkernel...
atags:0x413F2000
413F2000:EDFE0DD03AD5000048000000849E000028000000110000001000000000000000
413F2020:220700003C9E0000000000000040A84300000000EF7427000000000000000000
413F2040:0000000000000000010000000000000003000000040000000000000001000000
413F2060:03000000040000000F0000000100000003000000040000001B00000001000000
413F2080:03000000380000002C00000065697266796C646E2C6D7261796E697432313434
413F20A0:6D617300676E75737978652C34736F6E00323134736D61732C676E756E797865
413F20C0:0034736F030000002F0000003700000065697246796C646E204D5241594E4954
413F20E0:32313434616F62206220647264657361206E6F206E7978453434736F00003231
UncompressingLinux...done,bootingthekernel.
atags:0x413F2000
413F2000:EDFE0DD03AD5000048000000849E000028000000110000001000000000000000
413F2020:220700003C9E0000000000000040A84300000000EF7427000000000000000000
413F2040:0000000000000000010000000000000003000000040000000000000001000000
413F2060:03000000040000000F0000000100000003000000040000001B00000001000000
413F2080:03000000380000002C00000065697266796C646E2C6D7261796E697432313434
413F20A0:6D617300676E75737978652C34736F6E00323134736D61732C676E756E797865
413F20C0:0034736F030000002F0000003700000065697246796C646E204D5241594E4954
413F20E0:32313434616F62206220647264657361206E6F206E7978453434736F00003231
[0.000000]BootingLinuxonphysicalCPU0xa00
[0.000000]Linuxversion4.4.0-gbd49c0f-dirty(root@ubuntu)(gccversion4.8.320140320(prerelease)(SourceryCodeBenchLite2014.05-29))#25SMPPREEMPTTueJan1905:50:47PST2016
[0.000000]CPU:ARMv7Processor[413fc090]revision0(ARMv7),cr=10c5387d
[0.000000]CPU:PIPT/VIPTnonaliasingdatacache,VIPTaliasinginstructioncache
[0.000000]Machinemodel:FriendlyARMTINY4412boardbasedonExynos4412
[0.000000]bootconsole[earlycon0]enabled
[0.000000]cma:Reserved64MiBat0x7bc00000
[0.000000]Memorypolicy:Datacachewritealloc
[0.000000]SamsungCPUID:0xe4412011
[0.000000]PERCPU:Embedded12pages/cpu@ef79b000s18816r8192d22144u49152
[0.000000]Built1zonelistsinZoneorder,mobilitygroupingon.Totalpages:260352
[0.000000]Kernelcommandline:root=/dev/ram0rwrootfstype=ext4console=ttySAC0,115200init=/linuxrcearlyprintk
[0.000000]PIDhashtableentries:4096(order:2,16384bytes)
[0.000000]Dentrycachehashtableentries:131072(order:7,524288bytes)
[0.000000]Inode-cachehashtableentries:65536(order:6,262144bytes)
[0.000000]Memory:960824K/1047552Kavailable(5867Kkernelcode,293Krwdata,2288Krodata,440Kinit,315Kbss,21192Kreserved,65536Kcma-reserved,195584Khighmem)
[0.000000]Virtualkernelmemorylayout:
[0.000000]vector:0xffff0000-0xffff1000(4kB)
[0.000000]fixmap:0xffc00000-0xfff00000(3072kB)
[0.000000]vmalloc:0xf0800000-0xff800000(240MB)
[0.000000]lowmem:0xc0000000-0xf0000000(768MB)
[0.000000]pkmap:0xbfe00000-0xc0000000(2MB)
[0.000000]modules:0xbf000000-0xbfe00000(14MB)
[0.000000].text:0xc0008000-0xc07ff200(8157kB)
[0.000000].init:0xc0800000-0xc086e000(440kB)
[0.000000].data:0xc086e000-0xc08b7418(294kB)
[0.000000].bss:0xc08ba000-0xc0908d28(316kB)
可以看到UncompressingLinux...done,bootingthekernel.前后就是dump出的设备树的内容(大小端可能有些问题).
五、CONFIG_ARM_APPENDED_DTB
这个宏是Linux内核中的,它的作用是支持zImage+dtb的启动方式。为什么要有种方式呢?因为很多厂家都有自己的bootloader,但是这些bootloader并不都一定支持设备树,为了实现支持设备树启动,就引入了这种启动方式,即将编译出的zImage和编译出的设备树镜像文件拼成一个新的镜像,在内核的自解压代码中会识别到,不会出现自解压时导致设备树被覆盖,具体实现如下(arch/arm/boot/compressed/head.S)movr5,#0@initdtbsizeto0
#ifdefCONFIG_ARM_APPENDED_DTB
/*
*r0=delta
*r2=BSSstart
*r3=BSSend
*r4=finalkerneladdress(possiblywithLSBset)
*r5=appendeddtbsize(stillunknown)
*r6=_edata
*r7=architectureID
*r8=atags/devicetreepointer
*r9=sizeofdecompressedimage
*r10=endofthisimage,includingbss/stack/mallocspaceifnonXIP
*r11=GOTstart
*r12=GOTend
*sp=stackpointer
*
*iftherearedevicetrees(dtb)appendedtozImage,advancer10sothatthe
*dtbdatawillgetrelocatedalongwiththekernelifnecessary.
*/
ldrlr,[r6,#0]
#ifndef__ARMEB__
ldrr1,=0xedfe0dd0@sigis0xd00dfeedbigendian
#else
ldrr1,=0xd00dfeed
#endif
cmplr,r1
bnedtb_check_done@notfound
#ifdefCONFIG_ARM_ATAG_DTB_COMPAT
/*
*OK...Let'sdosomefunkybusinesshere.
*IfwedohaveaDTBappendedtozImage,andwedohave
*anATAGlistaround,wewantthelatertobetranslated
*andfoldedintotheformerhere.NoGOTfixuphasoccurred
*yet,butnoneofthecodewe'reabouttocallusesany
*globalvariable.
*/
/*GettheinitialDTBsize*/
ldrr5,[r6,#4]
#ifndef__ARMEB__
/*converttolittleendian*/
eorr1,r5,r5,ror#16
bicr1,r1,#0x00ff0000
movr5,r5,ror#8
eorr5,r5,r1,lsr#8
#endif
/*50%DTBgrowthshouldbegoodenough*/
addr5,r5,r5,lsr#1
/*preserve64-bitalignment*/
addr5,r5,#7
bicr5,r5,#7
/*clampto32KBminand1MBmax*/
cmpr5,#(1<;<15)
movlor5,#(1<;<15)
cmpr5,#(1<;<20)
movhir5,#(1<;<20)
/*temporarilyrelocatethestackpasttheDTBworkspace*/
addsp,sp,r5
stmfdsp!,{r0-r3,ip,lr}
movr0,r8
movr1,r6
movr2,r5
blatags_to_fdt
/*
*Ifreturnedvalueis1,thereisnoATAGatthelocation
*pointedbyr8.Trythetypical0x100offsetfromstart
*ofRAMandhopeforthebest.
*/
cmpr0,#1
subr0,r4,#TEXT_OFFSET
bicr0,r0,#1
addr0,r0,#0x100
movr1,r6
movr2,r5
bleqatags_to_fdt
ldmfdsp!,{r0-r3,ip,lr}
subsp,sp,r5
#endif
movr8,r6@usetheappendeddevicetree
/*
*MakesurethattheDTBdoesn'tendupinthefinal
*kernel's.bssarea.Todoso,weadjustthedecompressed
*kernelsizetocompensateifthat.bsssizeislarger
*thantherelocatedcode.
*/
ldrr5,=_kernel_bss_size
adrr1,wont_overwrite
subr1,r6,r1
subsr1,r5,r1
addhir9,r9,r1
/*GetthecurrentDTBsize*/
ldrr5,[r6,#4]
#ifndef__ARMEB__
/*convertr5(dtbsize)tolittleendian*/
eorr1,r5,r5,ror#16
bicr1,r1,#0x00ff0000
movr5,r5,ror#8
eorr5,r5,r1,lsr#8
#endif
/*preserve64-bitalignment*/
addr5,r5,#7
bicr5,r5,#7
/*relocatesomepointerspasttheappendeddtb*/
addr6,r6,r5
addr10,r10,r5
addsp,sp,r5
dtb_check_done:
#endif
拼接方法:
catzImagedts/exynos4412-tiny4412.dtb>dtbImage
也可以修改内核编译系统,在编译完成后自动实现拼接,可以参考下面的博文实现:
下面是使用dtbImage启动的方法:
1、修改设备树arch/arm/boot/dts/exynos4412-tiny4412.dts
diff--gita/arch/arm/boot/dts/exynos4412-tiny4412.dtsb/arch/arm/boot/dts/exynos4412-tiny4412.dts
index4840bbd..1e33ede100644
---a/arch/arm/boot/dts/exynos4412-tiny4412.dts
+++b/arch/arm/boot/dts/exynos4412-tiny4412.dts
@@-21,6+21,7@@
chosen{
stdout-path=&;serial_0;
+bootargs="root=/dev/ram0rwrootfstype=ext4ramdisk=8192initrd=0x41000000,8Mconsole=ttySAC0,115200init=/linuxrcmem=1024M"
};
memory{
@@-78,7+79,7@@
bus-width=<;4>;
pinctrl-0=<;&sd2_clk&sd2_cmd&sd2_cd&sd2_bus4>;
pinctrl-names="default";
-status="okay";
+status="disabled";
};
&;serial_0{
2、编译设备树makedtbs,将生成的.dtb跟zImag拼接起来生成dtbImage
3、使用ramdisk启动,目前不能使用ramdisk.img,还不知道为什么。
4、启动开发板,进入u-boot命令行模式,执行如下命令:
在u-boot里执行下载dtbImage的命令:dnw0x40008000
在开发机上执行:dnwdtbImage
在u-boot里执行下载ramdisk的命令:dnw0x41000000
在开发机上执行:dnwramdisk
启动内核:bootm0x40008000(u-boot不识别未压缩的ramdisk,ramdisk的地址在bootargs中指定为0x41000000,而且上面我们已经把ramdisk下载到0x41000000了)
下面是完整的log:
U-Boot2010.12-00000-gb391276-dirty(Jan172016-06:03:22)forTINY4412
CPU:S5PC220[SamsungSOConSMPPlatformBaseonARMCortexA9]
APLL=1400MHz,MPLL=800MHz
Board:TINY4412
DRAM:1023MiB
vdd_arm:1.2
vdd_int:1.0
vdd_mif:1.1
BL1version:N/A(TrustZoneEnabledBSP)
CheckingBootMode...SDMMC
REVISION:1.1
MMCDevice0:3803MB
MMCDevice1:3728MB
MMCDevice2:N/A
***Warning-usingdefaultenvironment
Net:Noethernetfound.
Hitanykeytostopautoboot:0
TINY4412#dnw0x40008000
OTGcableConnected!
Now,WaitingforDNWtotransmitdata
DownloadDone!!DownloadAddress:0x40008000,DownloadFilesize:0x446302
Checksumisbeingcalculated.....
ChecksumO.K.
TINY4412#dnw0x41000000
OTGcableConnected!
Now,WaitingforDNWtotransmitdata
DownloadDone!!DownloadAddress:0x41000000,DownloadFilesize:0x800000
Checksumisbeingcalculated.........
ChecksumO.K.
TINY4412#bootm0x40008000
BootwithzImage
Startingkernel...
atags:0x40CF68E8
40CF68E8:EDFE0DD072A5000038000000749E000028000000110000001000000000000000
40CF6908:FE0600003C9E0000000000000000000000000000000000000100000000000000
40CF6928:0300000004000000000000000100000003000000040000000F00000001000000
40CF6948:03000000040000001B0000000100000003000000380000002C00000065697266
40CF6968:796C646E2C6D7261796E6974323134346D617300676E75737978652C34736F6E
40CF6988:00323134736D61732C676E756E7978650034736F030000002F00000037000000
40CF69A8:65697246796C646E204D5241594E495432313434616F62206220647264657361
40CF69C8:206E6F206E7978453434736F0000323101000000736F686300006E6503000000
UncompressingLinux...done,bootingthekernel.
atags:0x40CF68E8
40CF68E8:EDFE0DD072A5000038000000749E000028000000110000001000000000000000
40CF6908:FE0600003C9E0000000000000000000000000000000000000100000000000000
40CF6928:0300000004000000000000000100000003000000040000000F00000001000000
40CF6948:03000000040000001B0000000100000003000000380000002C00000065697266
40CF6968:796C646E2C6D7261796E6974323134346D617300676E75737978652C34736F6E
40CF6988:00323134736D61732C676E756E7978650034736F030000002F00000037000000
40CF69A8:65697246796C646E204D5241594E495432313434616F62206220647264657361
40CF69C8:206E6F206E7978453434736F0000323101000000736F686300006E6503000000
[0.000000]BootingLinuxonphysicalCPU0xa00
[0.000000]Linuxversion4.4.0-gbd49c0f-dirty(root@ubuntu)(gccversion4.8.320140320(prerelease)(SourceryCodeBenchLite2014.05-29))#25SMPPREEMPTTueJan1905:50:47PST2016
[0.000000]CPU:ARMv7Processor[413fc090]revision0(ARMv7),cr=10c5387d
[0.000000]CPU:PIPT/VIPTnonaliasingdatacache,VIPTaliasinginstructioncache
[0.000000]Machinemodel:FriendlyARMTINY4412boardbasedonExynos4412
[0.000000]cma:Reserved64MiBat0x7c000000
[0.000000]Memorypolicy:Datacachewritealloc
[0.000000]SamsungCPUID:0xe4412011
[0.000000]PERCPU:Embedded12pages/cpu@ef79b000s18816r8192d22144u49152
[0.000000]Built1zonelistsinZoneorder,mobilitygroupingon.Totalpages:260608
[0.000000]Kernelcommandline:root=/dev/ram0rwrootfstype=ext4ramdisk=8192initrd=0x41000000,8Mconsole=ttySAC0,115200init=/linuxrcmem=1024M
[0.000000]PIDhashtableentries:4096(order:2,16384bytes)
[0.000000]Dentrycachehashtableentries:131072(order:7,524288bytes)
[0.000000]Inode-cachehashtableentries:65536(order:6,262144bytes)
[0.000000]Memory:956196K/1048576Kavailable(5867Kkernelcode,293Krwdata,2288Krodata,440Kinit,315Kbss,26844Kreserved,65536Kcma-reserved,196608Khighmem)
[0.000000]Virtualkernelmemorylayout:
[0.000000]vector:0xffff0000-0xffff1000(4kB)
[0.000000]fixmap:0xffc00000-0xfff00000(3072kB)
[0.000000]vmalloc:0xf0800000-0xff800000(240MB)
[0.000000]lowmem:0xc0000000-0xf0000000(768MB)
[0.000000]pkmap:0xbfe00000-0xc0000000(2MB)
[0.000000]modules:0xbf000000-0xbfe00000(14MB)
[0.000000].text:0xc0008000-0xc07ff200(8157kB)
[0.000000].init:0xc0800000-0xc086e000(440kB)
[0.000000].data:0xc086e000-0xc08b7418(294kB)
[0.000000].bss:0xc08ba000-0xc0908d28(316kB)
[0.000000]SLUB:HWalign=64,Order=0-3,MinObjects=0,CPUs=4,Nodes=1
[0.000000]PreemptiblehierarchicalRCUimplementation.
[0.000000]Build-timeadjustmentofleaffanoutto32.
[0.000000]RCUrestrictingCPUsfromNR_CPUS=8tonr_cpu_ids=4.
[0.000000]RCU:Adjustinggeometryforrcu_fanout_leaf=32,nr_cpu_ids=4
[0.000000]NR_IRQS:16nr_irqs:1616
[0.000000]GICphysicallocationis0x10490000
[0.000000]L2C:platformmodifiesauxcontrolregister:0x02070000->;0x3e470001
[0.000000]L2C:platformprovidedauxvaluespermitregistercorruption.
[0.000000]L2C:DT/platformmodifiesauxcontrolregister:0x02070000->;0x3e470001
[0.000000]L2C-310enablingearlyBRESPforCortex-A9
[0.000000]L2C-310:enablingfulllineofzerosbutnotenabledinCortex-A9
[0.000000]L2C-310dynamicclockgatingenabled,standbymodeenabled
[0.000000]L2C-310cachecontrollerenabled,16ways,1024kB
[0.000000]L2C-310:CACHE_ID0x4100c4c8,AUX_CTRL0x4e470001
[0.000000]Exynos4x12clocks:sclk_apll=466666667,sclk_mpll=800000000
[0.000000]sclk_epll=96000000,sclk_vpll=108000000,arm_clk=1400000000
[0.000000]Switchingtotimer-baseddelayloop,resolution41ns
[0.000000]clocksource:mct-frc:mask:0xffffffffmax_cycles:0xffffffff,max_idle_ns:79635851949ns
[0.000003]sched_clock:32bitsat24MHz,resolution41ns,wrapsevery89478484971ns
[0.000122]Console:colourdummydevice80x30
[0.000135]Calibratingdelayloop(skipped),valuecalculatedusingtimerfrequency..48.00BogoMIPS(lpj=120000)
[0.000144]pid_max:default:32768minimum:301
[0.000209]Mount-cachehashtableentries:2048(order:1,8192bytes)
[0.000217]Mountpoint-cachehashtableentries:2048(order:1,8192bytes)
[0.000586]CPU:Testingwritebuffercoherency:ok
[0.000772]CPU0:thread-1,cpu0,socket10,mpidr80000a00
[0.000999]Settingupstaticidentitymapfor0x400082c0-0x40008318
[0.045048]CPU1:thread-1,cpu1,socket10,mpidr80000a01
[0.060041]CPU2:thread-1,cpu2,socket10,mpidr80000a02
[0.075042]CPU3:thread-1,cpu3,socket10,mpidr80000a03
[0.075082]Broughtup4CPUs
[0.075096]SMP:Totalof4processorsactivated(192.00BogoMIPS).
[0.075101]CPU:AllCPU(s)startedinSVCmode.
[0.075611]devtmpfs:initialized
[0.084566]VFPsupportv0.3:implementor41architecture3part30variant9rev4
[0.084839]lcd0-power-domain@10023C80hasaschildsubdomain:tv-power-domain@10023C20.
[0.085225]clocksource:jiffies:mask:0xffffffffmax_cycles:0xffffffff,max_idle_ns:9556302231375000ns
[0.087164]pinctrlcore:initializedpinctrlsubsystem
[0.087929]NET:Registeredprotocolfamily16
[0.089226]DMA:preallocated256KiBpoolforatomiccoherentallocations
[0.105005]cpuidle:usinggovernorladder
[0.120000]cpuidle:usinggovernormenu
[0.120747]exynos-audss-clk3810000.clock-controller:setupcompleted
[0.157138]SCSIsubsysteminitialized
[0.157506]usbcore:registerednewinterfacedriverusbfs
[0.157580]usbcore:registerednewinterfacedriverhub
[0.157660]usbcore:registerednewdevicedriverusb
[0.158780]AdvancedLinuxSoundArchitectureDriverInitialized.
[0.159857]clocksource:Switchedtoclocksourcemct-frc
[0.169153]missingcooling_deviceproperty
[0.169163]failedtobuildthermalzonecpu-thermal:-2
[0.169260]NET:Registeredprotocolfamily2
[0.169627]TCPestablishedhashtableentries:8192(order:3,32768bytes)
[0.169686]TCPbindhashtableentries:8192(order:5,163840bytes)
[0.169803]TCP:Hashtablesconfigured(established8192bind8192)
[0.169921]UDPhashtableentries:512(order:2,24576bytes)
[0.169950]UDP-Litehashtableentries:512(order:2,24576bytes)
[0.170092]NET:Registeredprotocolfamily1
[0.170297]RPC:RegisterednamedUNIXsockettransportmodule.
[0.170305]RPC:Registeredudptransportmodule.
[0.170310]RPC:Registeredtcptransportmodule.
[0.170315]RPC:RegisteredtcpNFSv4.1backchanneltransportmodule.
[0.170461]Tryingtounpackrootfsimageasinitramfs...
[0.170628]rootfsimageisnotinitramfs(junkincompressedarchive);lookslikeaninitrd
[0.193515]Freeinginitrdmemory:8192K(c1000000-c1800000)
[0.194996]futexhashtableentries:1024(order:4,65536bytes)
[0.204233]romfs:ROMFSMTD(C)2007RedHat,Inc.
[0.204924]bounce:poolsize:64pages
[0.204936]ioschedulernoopregistered
[0.204945]ioschedulerdeadlineregistered
[0.205116]ioschedulercfqregistered(default)
[0.209955]dma-pl33012680000.pdma:LoadeddriverforPL330DMAC-141330
[0.209967]dma-pl33012680000.pdma:DBUFF-32x4bytesNum_Chans-8Num_Peri-32Num_Events-32
[0.213022]dma-pl33012690000.pdma:LoadeddriverforPL330DMAC-141330
[0.213032]dma-pl33012690000.pdma:DBUFF-32x4bytesNum_Chans-8Num_Peri-32Num_Events-32
[0.213909]dma-pl33012850000.mdma:LoadeddriverforPL330DMAC-141330
[0.213919]dma-pl33012850000.mdma:DBUFF-64x8bytesNum_Chans-8Num_Peri-1Num_Events-32
[0.271176]Serial:8250/16550driver,4ports,IRQsharingdisabled
[0.272413]13800000.serial:ttySAC0atMMIO0x13800000(irq=44,base_baud=0)isaS3C6400/10
[0.908554]console[ttySAC0]enabled
[0.912530]13810000.serial:ttySAC1atMMIO0x13810000(irq=45,base_baud=0)isaS3C6400/10
[0.921327]13820000.serial:ttySAC2atMMIO0x13820000(irq=46,base_baud=0)isaS3C6400/10
[0.930171]13830000.serial:ttySAC3atMMIO0x13830000(irq=47,base_baud=0)isaS3C6400/10
[0.939720][drm]Initializeddrm1.1.020060810
[0.953371]brd:moduleloaded
[0.958359]loop:moduleloaded
[0.959171]usbcore:registerednewinterfacedriverr8152
[0.959302]usbcore:registerednewinterfacedriverasix
[0.960434]usbcore:registerednewinterfacedriverax88179_178a
[0.966498]usbcore:registerednewinterfacedrivercdc_ether
[0.972325]usbcore:registerednewinterfacedriverdm9601
[0.977884]usbcore:registerednewinterfacedriversmsc75xx
[0.983611]usbcore:registerednewinterfacedriversmsc95xx
[0.989325]usbcore:registerednewinterfacedrivernet1080
[0.994965]usbcore:registerednewinterfacedrivercdc_subset
[1.000873]usbcore:registerednewinterfacedriverzaurus
[1.006454]usbcore:registerednewinterfacedrivercdc_ncm
[1.012397]ehci_hcd:USB2.0'Enhanced'HostController(EHCI)Driver
[1.018528]ehci-exynos:EHCIEXYNOSdriver
[1.022808]ohci_hcd:USB1.1'Open'HostController(OHCI)Driver
[1.028850]ohci-exynos:OHCIEXYNOSdriver
[1.033363]usbcore:registerednewinterfacedriverusb-storage
[1.039544]mousedev:PS/2mousedevicecommonforallmice
[1.045326]s3c-rtc10070000.rtc:failedtofindrtcsourceclock
[1.050645]s3c-rtc:probeof10070000.rtcfailedwitherror-2
[1.056739]i2c/deventriesdriver
[1.062046]device-mapper:ioctl:4.34.0-ioctl(2015-10-28)initialised:dm-devel@redhat.com
[1.069226]sdhci:SecureDigitalHostControllerInterfacedriver
[1.074585]sdhci:Copyright(c)PierreOssman
[1.079056]SynopsysDesignwareMultimediaCardInterfaceDriver
[1.086865]usbcore:registerednewinterfacedriverusbhid
[1.090471]usbhid:USBHIDcoredriver
[1.097222]NET:Registeredprotocolfamily10
[1.099233]sit:IPv6overIPv4tunnelingdriver
[1.103848]NET:Registeredprotocolfamily17
[1.107765]NET:Registeredprotocolfamily15
[1.112340]RegisteringSWP/SWPBemulationhandler
[1.118177]hctosys:unabletoopenrtcdevice(rtc0)
[1.134172]ALSAdevicelist:
[1.134208]Nosoundcardsfound.
[1.134917]RAMDISK:ext2filesystemfoundatblock0
[1.134972]RAMDISK:Loading8192KiB[1disk]intoramdisk...done.
[1.262918]EXT4-fs(ram0):mountedfilesystemwithreddatamode.Opts:(null)
[1.263014]VFS:Mountedroot(ext4filesystem)ondevice1:0.
[1.263132]devtmpfs:mounted
[1.263411]Freeingunusedkernelmemory:440K(c0800000-c086e000)
PleasepressEntertoactivatethisconsole.
[root@tiny4412]#
[root@tiny4412]#
相关文章推荐
- 基于tiny4412的Linux内核移植(支持device tree)(二)
- 基于tiny4412的Linux内核移植(支持device tree)(一)
- linux用sendmail发邮件
- 编译 Linux 3.5 内核烧写 Android 到tiny4412
- Linux下命令符操作(一)
- 《Linux内核设计与实现》学习总结 Chap5
- linux --> 系统信息命令
- linux内核模块时内核树的作用
- centos 6.5 搭建svn
- Linux中变量$#,$@,$0,$1,$2,$*,$$,$?的含义
- 使用systemd配置SVN服务器自动启动
- Linux将多网口虚拟为一个网卡
- Linux的启动流程
- linux中fork()函数详解(原创!!实例讲解)
- CentOS进入单用户模式
- 用户的主要群组和次要群组
- 移植最新内核linux-3.14.6到mini2440开发板
- linux命令:top命令
- linux命令:kill命令
- Linux内核设计第五周学习总结 分析system_call中断处理过程