2018/08/12 21:39
有道云地址:http://note.youdao.com/noteshare?id=9ab91347c6ce1b15ef0c3fa8e8a60605&sub=612AF77E36994945B6638F4B884E286C
太大了,这里就不高亮各处关键点了,详细查看有道云笔记。
(转https://blog.csdn.net/u011523533/article/details/49278901)
因为要开发Hadoop应用,所以在笔记本上安装了VMware虚拟机。下面将记录我安装完成后,建立网络连接的过程。
1.确保安装完VMware虚拟机和ubuntu系统
2.安装完虚拟机后,在本地系统的网络中心可以看到
其中,VMnet8即为我们需要使用的网卡。
需要关注下IP地址。
4.打开虚拟机,在编辑-》虚拟网络编辑器中
PermitRootLogin without-password
可以看到有一个NAT模式,请确保NAT模式下的子网地址与刚才我们在VMnet8网卡查看到的IP地址处于同网段,点击NAT模式,点击下面的设置按钮,请记住网关Ip地址,unbuntu
设置时需要使用。
5.在命令终端中,输入 sudo vi /etc/network/interfaces 并添加以下内容
# interfaces(5) file used by ifup(8) and ifdown(8)
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet static
address 192.168.117.100
netmask 255.255.255.0
gateway 192.168.117.2
dns-nameservers 8.8.8.8
其中 address 的数值取同网段的任意值,注意不要跟已使用的重复
gateway 的数值即为刚才记住的网关Ip地址
netmask 数值为255.255.255.0
最后一行为DNS服务器,可以直接写8.8.8.8
6.保存退出后,重启系统即可
为了使用SSH和sshsecureshell远程登录ubuntu
保证虚拟机设置为物理网络,且开发板已经连接到电脑,
因为windows系统中有一个bug,如果windows没有检测到有线网卡连接了外部网络则windows中本地连接是不工作的,网卡不工作。解决方案是用网线随便连接一个有联网能力的东西即可,譬如网线连接你的电脑到旁边兄弟的电脑上,譬如插上你的开发板(开发板中运行了linux系统),
否则,ubuntu下ping windows可能会失败哦。
(1)安装ssh-server。
(输入命令:sudo apt-get install openssh-server)
如果报错提示依赖错误,可以参考:http://www.cnblogs.com/mliudong/p/4094519.html
(2)securecrt登录
(3)sshsecureshell登录
过程中出现的问题:
在ubuntu中已经可以ping通windows的情况下,设置好securecrt和SSH远程登录ubuntu都显示口令验证失败这种情况
解决方法:在ubuntu中输入命令: vi /etc/ssh/sshd_config
将 PermitRootLogin 这一项的值改为 yes ,保存退出。重启系统,即可
问题原因:
sshd_config 是sshd的配置文件,其中PermitRootLogin
可以限定root用户通过ssh的登录方式,如禁止密码登录等,设置为yes,即允许ssh登录
1、直接编译三星移植版uboot尝试运行
(1)复制到linux的源生目录下,然后解压开。
(2)检查Makefile中的交叉编译工具链
在解压后的文件中,打开Makefile
(3)配置时使用:make smdkv210single_config
对应include/configs/smdkv210single.h头文件。
(4)配置完成后直接make编译,编译完成后就进入烧录步骤。
(5)uboot/sd_fusing目录下有sd_fusing.sh脚本,用来烧录
(6)烧录到SD卡过程,
先file sd_fdisk 查看工具的环境是否为主机环境,很明显不是。
**先make distclean ,make
smdkv210single_config,再次make,之后查看工具的环境,为我们主机的inter环境**
使用命令./sd_fusing.sh /dev/sdb 烧录到SD卡
下载到SD卡后,启动开发板,运行结果是:SD checksum Error,
第一,串口无输出;第二,开发板供电锁存成功。
2、代码分析&问题查找
分析运行结果:uboot中串口最早的输出在”OK”,在lowlevel_init.S中初始化串口时打印出来的;串口无输出”O”说明在打印”O”之前代码已经死掉了;开发板供电锁存在lowlevel_init.S中,开发板供电锁存成功说明这个代码之前的部分是没问题的。两个结合起来得到结论:错误在开发板供电锁存代码和串口初始化打印”O”代码之间。
前提:使用SourceInsight 建立工程及添加文件
(1)首先要创建一个工程。菜单栏:Project->new project。
(2)工程项目文件和工程中管理的源代码文件目录可以不同,但是我一般习惯放在一起。放在:E:\Linux\2.Uboot_DEMO\uboot\android_uboot_smdkv210\u-boot-samsung-dev\Si_Proj
SI_Proj是自己建的工程目录
点确定,进入new project setting,直接点ok进入下一步。
(3)到了向项目中添加文件的步骤。
在左侧选择uboot-jiuding这个目录,然后点右侧边栏的add tree即可添加。
(4)本来应该已经结束了,但是有遗留问题。因为SI软件有个特点,它只能发现自己识别了的文件类型,对于它未识别的文件类型它就看不到。譬如start.S文件就未包含在内,因为SI默认不认识.S后缀的文件。
解决方案:第一种是自己配置;
(5)解决了4中的问题然后再次添加文件。菜单栏 Project->Add and Remove Project
Files 再次浏览到uboot-jiuding目录下,再次add tree,发现添加了额外的19个文件。
2.解析工程文件
我们使用SI查阅源码前应该预先进行源码解析,为了让SI查找速度变得快
在菜单栏Project->Syneronize Files,选中上面2个,然后确定。
3、PMIC模块的修改
由于开发板供电锁存是正常的,进入uboot工程中的start.S文件查阅lowlevel_init查阅供电锁存后的代码,发现Smart210无PMIC模块,将其注释
这是在windows中修改的,需要将其拷贝到linux下,
使用如下命令:
cp
/mnt/hgfs/Linux/2.Uboot_DEMO/uboot/android_uboot_smdkv210/u-boot-samsung-dev/board/samsung/smdkc110/lowlevel_init.S
./board/samsung/smdkc110/ -f
在cp.sh中输入一下信息,后面的修改都可以写在cp.sh中,执行该脚本即可。
\# 文件复制
\# 复制 board/samsung/smdkc110/lowlevel_init.S
cp
/mnt/hgfs/Linux/2.Uboot_DEMO/uboot/android_uboot_smdkv210/u-boot-samsung-dev/board/samsung/smdkc110/lowlevel_init.S
./board/samsung/smdkc110/ -f
vi board/samsung/smdkc110/lowlevel_init.S
整个uboot就启动起来了。但是很多配置信息是有问题的,很多功能应该也是不能用的,都要去一一查验。下面我们就这些问题一一检测修改。
在cp.sh中输入一下信息,更改后执行cp.sh脚本
#复制 **/include/configs/smdkv210single.h**
cp /mnt/hgfs/Linux/2.Uboot_DEMO/uboot/android_uboot_smdkv210/u-boot-samsung-de
v/include/configs/smdkv210single.h ./include/configs/ -f
1、更改CONFIG_IDENT_STRING为” for ALIYA210”,
然后同步到ubuntu中的一份代码,然后 make distclean; make
smdkv210single_config,然后make,然后烧录运行,检查打印出来的banner信息是否如我们改动的那样。
2、确认时钟部分的配置
(1)时钟部分的运行结果本来就是对的,时钟部分的代码在lowlevel_init.S中的bl
system_clock_init调用的这个函数中。函数的代码部分是没任何问题的,根本不需要改动,要改动的是寄存器写入的值,这些值都在配置头文件(smdkv210single.h)中用宏定义定义出来了。如果时钟部分要更改,关键是去更改头文件中的宏定义。
(2)三星移植时已经把210常用的各种时钟配置全都计算好用宏开关来控制了。只要打开相应的宏开关就能将系统配置为各种不同的频率。我们这里不需要更改
3、DDR配置信息的更改
S5PV210共有2个内存端口(就好象有2个内存插槽)。再结合查阅数据手册中内存映射部分,可知:
两个内存端口分别叫DRAM0和DRAM1:
DRAM0:内存地址范围:0x20000000~0x3FFFFFFF(512MB),对应引脚是Xm1xxxx
DRAM1: 内存地址范围:0x40000000~0x7FFFFFFF(1024MB),对应引脚是Xm2xxxx
结论:
(1)整个210最多支持内存为1.5GB,如果给210更多的内存CPU就无法识别。
(2)210最多支持1.5GB内存,但是实际开发板不一定要这么多,譬如我们X210开发板就只有512MB内存,连接方法是在DRAM0端口分布256MB,在DRAM1端口分布了256MB。
(3)由2可知,**X210开发板上内存合法地址是:0x20000000~0x2FFFFFFF(256MB) +
0x40000000~0x4FFFFFFF(256MB)**。当板子上DDR初始化完成之后,这些地址都是可以使用的;如果使用了其他地址譬如0x30004000就是死路一条。
(1)从运行信息以及bdinfo命令看到的结果,显示DRAM bank0和1的size值都设置错了。
(2)使用md和mw命令测试内存,发现20000000和40000000开头的内存都是可以用的,说明代码中DDR初始化部分是正确的,只是size错了。
(3)内存部分配置成:
\#define CONFIG_NR_DRAM_BANKS 2 /\* we have 2 bank of DRAM \*/
//\#define SDRAM_BANK_SIZE 0x20000000 /\* 512 MB \*/
\#define SDRAM_BANK_SIZE 0x10000000 /\* 256 MB \*/
\#define PHYS_SDRAM_1 MEMORY_BASE_ADDRESS /\* SDRAM Bank \#1 \*/
\#define PHYS_SDRAM_1_SIZE SDRAM_BANK_SIZE
//\#define PHYS_SDRAM_2 (MEMORY_BASE_ADDRESS + SDRAM_BANK_SIZE) /\* SDRAM Bank
\#2 \*/
\#define PHYS_SDRAM_2 0x40000000
\#define PHYS_SDRAM_2_SIZE SDRAM_BANK_SIZE
(4)执行cp.sh脚本,重新make编译后,烧录到SD卡,启动开发板,显示如下:修改DDR信息成功
4.DDR地址另外配置.
(1)、目标:将DDR端口0地址配置为30000000开头
(1)更改有2个目的:第一是让大家体验内存配置的更改过程;第二是3开头的地址和DRAM
bank1上40000000开头的地址就连起来了。这样我们就得到了地址连续的512MB内存,而原来我们得到的512MB内存地址是断续的。
(2)、DDR初始化参数更改
(1)根据裸机中讲DDR初始化部分的课程,和uboot前面分析uboot中DDR初始化部分的代码的课程,得出结论就是:DDR的初始化代码部分是在lowlevel_init.S中写的,是不动的。代码部分就是对相应寄存器做相应值的初始化;要动的是值,而uboot为了具有可移植性把值都宏定义在include/configs/xxx.h中了。因此我们只需要去这个配置头文件中更改配置值即可。
(2)更改内容是:#define DMC0_MEMCONFIG_0 0x20E01323改为:
**#define DMC0_MEMCONFIG_0 0x30E01323 注意20改为30了。
(3)、smdkv210single.h中相关宏定义修改
(1)寄存器的值改了后相当于是硬件配置部分做了更改。但是uboot中DDR相关的一些软件配置值还没更改,还在原来位置,所以要去更改。
(2)#define MEMORY_BASE_ADDRESS 0x20000000改为:
#define MEMORY_BASE_ADDRESS 0x30000000
(4)、虚拟地址映射表中相应修改
(1)uboot中开启了MMU对内存进行了段式映射,有一张内存映射表。之前课程中分析过,分析方法是一样的。
(2)经过实际分析,发现这个内存映射只是把20000000开始的256MB映射到C0000000开头的256MB。我们更改方法是将2改成3.
(3)为了安全起见,再去配置头文件smdkv210single.h中查一遍,看看有没有其他的宏定义值和内存配置有关联的。
在这里,看到MMU的设置,可以也可以不修改,因为我们我们设置了MMU,不会走0x23e00000这个地址。为了严谨起见,还是设置为0x33e00000
重新配置编译,烧录运行查看结果。
可以看出,是有问题的。(只打印了ok,说明uboot第一阶段运行了,死在了第二阶段还没运行),下节排查问题。
5.DDR初始化参数更改2
(1)、修改DMC0的配置参数
#define DMC0_MEMCONFIG_0 0x30E01323 改为:
**#define DMC0_MEMCONFIG_0 0x30F01323**
(2)、修改修改虚拟地址到物理地址的映射函数
至此,uboot中的DDR移植就已经结束了
1、先从现象出发定位问题
从打印出来的错误休息中挑选一个关键词EXT_CSD,然后去源代码中搜索这个关键字,通过这种搜索的方法定位问题。找到该关键字的文件函数为mmc_read_ext_csd函数,通过从头分析该函数。
通过搜索将问题定位在drivers/mmc/mmc.c的818行。
发现这个函数是在读取SD/iNand的ext_csd寄存器的值。通过浏览代码结合出错地方,可以判断出:从卡端读取ext_csd寄存器是成功的,并且从读取结果中拿到了卡的版本号信息。然后代码对版本号进行了判断,并且如果版本号大于5就会报错并且函数错误退出。这就是问题所在。
(2)问题就是:我们使用的iNand卡的版本号大于5,而uboot代码本身不处理版本号大于5的卡,因此出错了。
2、网络搜索解决方案
网络搜索错误关键字,然后逐个去查阅,看看哪个可以给我们提供解决问题的思路和方法。http://blog.csdn.net/wang_shuai_ww/article/details/22308853
3、尝试修改代码解决问题
由上面的博客了解到,解决方法就是修改uboot中的代码,把判断的5改成更大的数字。譬如8,然后跳过这个错误。
在cp.sh脚本中添加如下命令
然后烧录下载进去,即解决了这个问题
4、推测和实验验证(SD卡和iNand的区别)
(1)当前板子上有一个iNand接在SD0上,有一个外置SD卡接在SD2上。那uboot中初始化的这个是iNand而不是SD卡。也就是说uboot中实际用的是SD0而不是SD2.
(2)大家可以尝试,使用外置SD卡时,这个版本号的问题不会出现。从这里可以推测出SD卡和iNand的区别,至少从一个角度可以看出:SD卡版本低,iNand的版本比较高。
1、控制台串口更换为串口0
(1)uboot中默认使用串口2来做控制台输入输出的。
(2)SOC中一共有4个串口(串口0、1、2、3),开发板X210上用DB9接口引出了2个串口,分别是串口2和串口0.(靠边的是串口2,靠里那个是串口0)。
(3)有时候项目需要将调试串口修改为另外的串口(譬如串口0),这时候需要修改uboot的代码,做移植让uboot工作在串口0的控制台下。
(4)uboot中真正去硬件初始化串口控制器的代码在lowlevel_init.S中的uart_asm_init中其中初始化串口的寄存器用ELFIN_UART_CONSOLE_BASE宏作为串口n的寄存器的基地址,结合偏移量对寄存器进行寻址初始化。
所以uart_asm_init中到底初始化的是串口几(从0到3)取决于ELFIN_UART_CONSOLE_BASE宏。
这个宏的值又由CONFIG_SERIALn(n是从1到4)来决定
(5). CONFIG_SERIALn的宏定义在Smdkv210single.h中,我们需要串口0,
即只需要将宏定义更改为CONFIG_SERIAL1
(6)同步代码(cp.sh脚本)、编译烧录运行,发现串口线插在串口2上,crt上只打印:SD
checksum
error.(这个是内部iROM打印出来的,内部iNand校验失败的信息);然后将串口线改插到串口0上,启动,所有的信息出现。实验成功。
2、修改默认网络地址设置
(1)修改配置头文件smdkv210single.h中的CONFIG_IPADDR等宏,则可以修改uboot的默认环境变量。(就不用每次在终端上save修改环境变量了)
3、修改行提示符
(1)#define CFG_PROMPT “ASTON210 # “
4、同步代码(cp.sh脚本)、编译烧录到SD卡运行和期望的一样。
注意:
(1)更改完成后如果环境变量还是原来的,正常。因为原来uboot执行过saveenv,因此环境变量已经被保存到iNand中的ENV分区中去了。uboot启动后校验时iNand的ENV分区中的环境变量是正确的,因此会优先加载。我们在uboot源代码中修改的只是默认的环境变量。解决方案是擦除掉iNand中的那一份环境变量,然后迫使uboot启动时使用uboot代码中自带的默认的这一份环境变量,就可以看到了。
(2)擦除掉iNand中的那一份环境变量:可以使用命令:mmc write 0 30000000 11# 32
(表示将DDR的0x30000000开头的一段内存中的内容写入iNand中的第17个扇区开始的32个扇区内,写入长度是32个扇区长度(16KB))
1、网卡芯片与开发板的连接方式
(1)SoC的SROM
bank和网卡芯片的CS引脚(SROM就是SRAM/ROM)。SoC的SROMController其实就是SoC提供的对外总线式连接SRAM/ROM的接口。如果SoC要外部外接一些SRAM/ROM类的存储芯片(或者伪装成SROM接口的芯片,譬如网卡芯片)就要通过SROM
Controller来连接。网卡接在SROM中好处就是网卡芯片好像一个存储芯片一样被扩展在SoC的一个地址空间中,主机SoC可以直接用一个地址来访问网卡芯片内部寄存器。
(2)网卡芯片内部寄存器使用相对地址访问。网卡芯片内部很多寄存器有一个地址,这个地址是从00开始的,但是实际上我们SoC不能用0地址去访问这个网卡的芯片内部寄存器。
**SoC访问网卡芯片00寄存器时的地址应该是:起始地址+00这里的起始地址就是网卡芯片对应接在SROM
bankn中的bankn对应的基地址。**
(3)总结:网卡实际上也是一种总线式连接方式。优势是SoC内部不需要内置网卡控制器,所有的SFR全都在外部网卡芯片中,而且还可以通过地址直接访问(IO与内存统一编址),不用像Nand/SD接口一样使用时序来访问。
2.原理图浏览
(1).
根据210开发板底板电路原理图DM9000网卡的电路原理图可知,210的SROM控制器允许8/16bit的接口,我们实际使用的是16位接口。
(2)网卡芯片有个CS引脚,(**CS就是chip
select,片选信号,主机向CS发送有效信号则从机芯片工作,主机向CS发送无效信号则从机芯片不工作。**),
(3)这个引脚要接主机SoC的片选信号引脚,主机S5PV210的每一个SROM
bank中有一个片选信号CSn(n=0-5),从原理图可以看出,**我们X210上将DM9000的CS引脚接到了CSn1上,对应SROM
bank1(推断出DM9000的总线地址基地址是0x88000000)。**
(4)DM9000的CMD引脚接到了S5PV210的ADDR2引脚上。访问DM9000数据的地址0x88000000+0b100((0b100,对应原理图连接的ADDR2)。*DM9000为了减少芯片引脚数,数据线和地址线是复用的(DATA0到DATA15这16根线是有时候做数据线传输数据,有时候做地址线传输地址的。什么时候做什么用就由CMD引脚决定。)通过查询数据手册知道:当CMD为高电平时对应传输是DATA,当CMD为低电平时对应传输为INDEX(offset,寄存器地址)。*
dm9000_pre_init函数位于board/samsung/smdkc110/smdkc110.c文件中
1.由前面学习的uboot启动第二阶段可知,网卡初始化代码地方在board_init函数中,该函数里面的关键是dm9000_pre_init函数,这个函数就是移植的关键
2.dm9000_pre_init函数主要功能就是初始化DM9000网卡。这个初始化过程和我们开发板上DM9000网卡芯片的硬件连接方式有关。必须要结合开发板原理图来分析,然后决定这个函数怎么编程。
该函数用到了3个寄存器,查看S5PV210_UM_REV1.1.pdf,结合数据手册修改源码。
(1)#define DM9000_16BIT_DATA这个宏用来表示DM9000工作在16位总线模式下。
三星的开发板DM9000是接在Bank5上的。
而我们接在bank1上的,我们需要操作的bit位是bit4-bit7
(2)三星的开发板DM9000是接在Bank5上的。而我们接在bank1上的
(3)
3.总结:三个寄存器的修改。主要是三星的开发板DM9000接在bank5,我们接在了bank1上,因此要做一些修改。
4.基地址的配置等
修改uboot中开发板配置头文件include/configs/smdkv210single.h
(1)CONFIG_DM9000_BASE是DM9000网卡通过SROM
bank映射到SoC中地址空间中的地址。这个地址的值取决于硬件接到了哪个bank,这个bank的基地址是SoC自己定义好的。譬如我们这里接到了bank1上,bank1的基地址是0x88000000.(详情查看地址表如下)
//#define CONFIG_DM9000_BASE (0xA8000000)
#define CONFIG_DM9000_BASE (0x88000000)
(2)DM9000_IO表示访问芯片IO的基地址,直接就CONFIG_DM9000_BASE;DM9000_DATA表示我们访问数据时的基地址,上面分析原理图,知DM9000芯片的CMD引脚接到了ADDR2,因此这里要+4(0b100,对应ADDR2)
//#define DM9000_DATA (CONFIG_DM9000_BASE+2)
#define DM9000_DATA (CONFIG_DM9000_BASE+4)
(3)本来这样配置就完了,重新编译运行网卡就应该工作了。但是实际测试发现不工作,要怎么样修改呢?修改方式是将CONFIG_DM9000_BASE改成0x88000300就工作了。
烧录进去显示如下:
我得出的感觉最靠谱的解释是:跟DM9000网卡芯片型号版本有关,我认为这个0x300是DM9000网卡本身的问题,他本身的内部寄存器就有一个0x300的一个偏移量。
到这里,网卡DM9000在uboot中的移植就完成了。那么移植好了uboot,肯定得拿来启动内核,如果不能启动内核,那uboot将毫无意义!
1、问题:当前uboot能启动内核,但是内核启动中出现问题(未完全启动)
排查问题:
(1)用同样的方法(使用tftp 0x30008000 zImage-qt; 然后bootm 0x30008000)
启动内核成功,但是终端打印内核信息未完全启动
排查原因:bootcmd bootargs参数有问题
set bootcmd 'movi read kernel 30008000; movi read rootfs 30B00000 300000; bootm
30008000 30B00000'
setenv bootargs "console=ttySAC2,115200 root=/dev/mmcblk0p2 rw init=/linuxrc
rootfstype=ext3"
然后save保存。
2、根据现象分析,定位问题并试图解决
(1)如果已经启动了内核,那没什么好说的了。应该是可以直接启动了。
(2)如何内核没有启动,是smdkv210single.h中没有定义bootm传参需要的那几个宏造成的。
1、linux系统中网卡驱动的典型工作方式简介
(1)在linux系统中,网卡算是一个设备,这个设备驱动工作后会生成一个设备名叫ethn(n是0、1、2、····)(无线网卡名字一般叫wlan0、wlan1····)。然后linux系统用一些专用命令来操作网卡,譬如ifconfig命令。
(2)linux下的应用程序如何使用网卡驱动来进行网络通信?最通用的方法就是socket接口。linux系统中有一系列的API和库函数,提供了一个socket编程接口,linux下的应用程序都是通过socket来实现上网的,socket内部就是间接调用的网卡驱动实现网络通信的。
(3)linux设计是非常完备的,应用层和驱动层是严格分离的。也就是说写网络编程应用层的人根本不用管驱动,只要会用socket接口即可;写底层驱动的人根本不用管应用层,只要面向linux的网络驱动框架模型即可。
2、uboot中网卡驱动的工作方式简介
(1)一定要记住:uboot本身是一个裸机程序,是一个整体,没有分层。所以uboot中根本没有驱动和应用的概念。
(2)按照逻辑来说,ping这样的命令实现的代码就是网络应用的应用程序,像dm9000x.c和dm9000x.h这样的代码属于驱动程序。所以在uboot中这些东西是揉在一起的,应用是直接调用驱动实现的。也就是说ping命令内部是直接调用了dm9000的网卡驱动中的函数来实现自己的。
3、以ping命令为例查找代码验证分析
(1)ping命令是uboot的众多命令之一,ping命令实现的函数叫do_ping
(2)函数的调用关系:
(3)验证了2.11.11.3中说的uboot中应用程序(ping)调用驱动程序(dm9000x.c)的方式。这就是一种直接调用的方式。
注:lcd驱动与logo显示,在2.13.uboot杂记-logo显示和fastboot原理等中详解