这里说一些万一产生开HTTP通信的付出要看一下RFC中对两样版本HTTP的概念。KDE是属于德国之精工务实派。所以共有27清数据线。

   
想开始陆续研究有谢谢兴趣之开源代码于是先挑一个代码量短的来连接一下,写这篇博客的目的是记录下自己学习之过程。Tinyhttpd算是一个小型的web服务器,浏览器和Web服务器之间的通信采用的是Http,所以同样开始的切入点是HTTP协议,这里说一些使来召开HTTP通信的出还是看一下RFC中对两样版本HTTP的定义,以下原理部分还是自《后台开发:核心技术与运用实践》中HTTP协议章节中推出来的,对后令感兴趣的同桌可以拘留一下,讲述后台开发所急需有所的技艺点同样依照颇对的写。

GNOME的窗口焦点问题让自己喷血,终于要于坚守多年底GNOME切换到了KDE。

1.nor硬件介绍:

一、HTTP协议

 

 图片 1

HTTP工作流程:

撇开开kde的认可问题不发话。KDE是属于德国底精工务实派,GNOME是属美国的骄傲轻浮派,难怪redhat等几寒主要的都推G,而suse推k。

自规律图中我们能望NOR
FLASH有地址线,有数据线,它跟咱们的SDRAM接口相似,能直接读取数据,但是非克像SDRAM直接写副数据,需要出指令才行

  于OSI七层模型中,HTTP是基于TCP上之应用层协议如果我们所说的HTTPS基于同处应用层的TLS、SSL协议层之上。HTTP默认的捧口号为80,HTTPS默认的端口号也443。在HTTP1.1蒙(通过Connection头设置)默认在HTTP传输就后持续开TCP连接,在此之前的HTTP版本则默认是断开连接的,也就是说这次请和上次请求是不同的有限单TCP连接。一次等HTTP操作称为一个事情,其工作经过得分为以下四步。

1.1中间我们2440之地址线共有27到底(LADDR0~26),为什么是27干净?

  (1)首先客户机与服务器需要树立连接 。 只要单击某个超级链接, HTTP
的工作就是开 。
  (2)建立连接后,客户机发送一个伸手于服务器,请求方式的格式为:统一资源标识符(URL
)、协议版本号,后边是 MIME
信息(包括要修饰符、客户机信息及可能的始末) 。

坐2440旅产生7只bank内存块,每个bank=128MB=(2^27)B,所以共有27根本数据线

  (3)服务器收到请求后,给予对应的应信息,其格式为一个状态行,包括信息之协议版本号、一个打响还是不当的代码,后边是
MTh伍信息(包括服务器信息、实体信息和可能的情节) 。

1.2怎么Nor
Flash的地址线A0是连接在2440之LADDR1上?

  (4)客户端接收服务器所返的信经过浏览器显示在用户之显示屏上,然后客户机与服务器断开连接

因Nor
Flash的多寡共有16员,也不怕是每个地方保存了2B数码,而我们的2440每个地方是保留之1B数据,

HTTP协议结构:

比如:

  HTTP 协议无论是请求报文还是答应报文,都分为以下 4 只片 。

当2440访问问0X00地址时,就会见读取到Nor上0地址的2B数据,然后2440的内存控制器会根据0x00来找到低8员字节,并回给CPU,

  (1)报文头( initial line ),上面的例子中之“ GET
http://www.baidu.com/favicon.icoHTTP/1.1 ”表示为此 GET 方法要
http://www.baidu.com/favicon. ic。这个文件,用底凡HTTP/1.1 协议。

当2440看问0x01地址时,由于2440之LADDR0线未联网,所以要看Nor的0地址上之2B数据,然后内存控制器会依据0x01来找到高8位字节,并回给CPU

  (2) 0 只或多独请求头( header line ),例如 Accept-Language: en

1.3
nand和nor区别:

  (3)空行(作为 header lines 的结束) 。

nor flash于价钱达成比nand贵,且容量非常小
,擦除和描写多少还缓,好处在接口简单,稳定,无位反转,坏块,常用于保存要数据,而nand
flash常用于保存好容量数据

  (4)可卜的消息体 。

于2440蒙受凡是经过硬件开关来设置OM0为Nand启动或Nor启动,如下图所示:

  HTTP 协议是根据行之协议,每一样履 以 \r\n 作为分隔符 。
报文头通常表明报文的路(例如请求类型),且报文头只占一行
;请求头附带一些特有信息,每一个央求头占一执行,其格式为 name:value
,即以分行作为分隔; 空行也不怕因为一个 \r\n 分隔;可选 body
通常含数据,例如服务器返回的某静态 HTML 文件的情 。

 图片 2

  HTTP请求方法:

OM0有血有肉参数如下所示,其中2440底OM1挑起脚默认接地

  HTTP/ 1.1 协议中共定义了 9 栽方法(有时也给“动作”)来表 明
Request-URI 指定的资源的不同操作办法,如下所陈述。

 图片 3

  ( 1 ) OPTIONS :返回服务器对特定资源所支持的 HTTP
请求方法;也得采用为 Web服务器发送“*”的请求来测试服务器的功能性。

于nand启动:OM0衔接地,nand
flash的初步4KB会自动地吃加载到2440平放的SRAM缓存器中,就好直接读写

  ( 2) HEAD :向服务器需要和 GET
请求相平等的响应,只不过响应体将非会见于归 。
这同智可以当不必传输整个响应内容之景象下,就好取包含在应消息头挨之老大信息
。该方法常用于测试超过链接的可行,是否可看,以及最近是不是更新等消息

于nor启动:OM0连贯大,2440看的内存就是nor
flash,可以直接读,但是未可知一直写

  ( 3) GET :向特定的资源发出请求 。 注意 : GET
方法不该于用于产生“副作用”的操作着,例如在 web app .
中的使,其中一个原因是 GET 可能会见让网蜘蛛等任意访问 。

 

  ( 4 ) POST
:向指定资源提交数据进行拍卖要(例如提交表单或者达到传文书) 。
数据被含有在求求体中 。 POST
请求或会见造成新的资源的确立或者对都生资源的修改 。

2.nor
flash命令如下所示(参考MX29LV160DBTI.pdf)

  ( 5 ) PUT :向指定资源职务上传其最新内容 。

 图片 4

  ( 6) DELETE : 请求服务器删除 Request-URI 所标识的资源 。

其中word是针对16位nand,byte针对8位nand.

  ( 7 ) TRACE :回显服务器收到的伸手,主要用以测试或确诊。

鉴于我们2440底flash型号是MX29LV160DB,所以设备ID为0x2249

  ( 8) CONNECT: HTTP/ 1.1
协议被留给给能够以连改也管道方式的代理服务器 。

 

  ( 9) PATCH :用来拿部分修改以被某某平资源,该操作添加于规范盯C5789
中 。

2.1
比如,当我们设program(往0x20地址写入0xff数据)时

  HTTP 服务器至少应该实现 GET 和 HEAD 方法,其他办法还是可选的 。
此外,除了上述方式,特定的 HTTP 服务器还能扩大自定义的主意 。

用以下3步:

  HTTP 常见的呼吁头:

1.发送解锁地址:

  于 HTTP/ l.l 协议中,所有的请求头(除 Host
外)都是可选的,因为Host主要用来请求的服务器的IP地址及端口号,请求头有Host、Connection、Accept、Accept-Encoding、User-Agent、Cookie等,请求头太多这里就不排出来了。

往nor地址0x555写入0xAA

  HTTP回应报文:

往nor地址0x2AA写入0x55 

  返回码由 3 员数字组成,第一单数字定义了响应的型,且有 5
种可能的取值。

2.殡葬命令:     

  ( 1 ) lxx :指示信息,表示求都收取,继续处理。

往nor地址0x555写入0xA0               
//进入program模式

  ( 2) 2xx :成功,表示求都让成功接收、理解 、 接受 。

3.写数据:

  ( 3) 3xx :重定向,要就请求必须进行重复进一步的操作 。

往nor地址0x20(PA)写入0xff(PD)         
//往0x20写入0xff

  ( 4 ) 4xx :客户端错误,请求有语法错误或要无法兑现。

(接下就是见面一直是program模式,执行reset模式就是可以退出)

  ( 5) 5xx :服务器端错误,服务器未能落实合法的请 。

2.2拖欠NOR有些许种植标准,
jedec, cfi(common flash interface) 

  Date :表示消息发送的时日,时间的叙述格式由 rfc822 定义 。

jedec

  Server : 指明 Web 服务器用来拍卖要的软件信息 。

就是和nandflash的一样,通过读ID来匹配linux内核中drivers/mtd/chips/jedec_probe.c里的jedec_table[]数组,来确定norflash的次第参数(名称、容量、位宽等),如下图所示:

  Accept-Ranges : Web
服务器表明自己是否接受获取其有实体的一致片段(比如文件之等同组成部分)的请求
。 bytes 表示接受, none 表示未收取。

 图片 5

  Vary: Web 服务器用该头部的内容告诉 Cache
服务器,在啊条件下才能够为此本应所返的目标应后续之请 。

  • [0] =
    MTD_UADDR_0x5555_0x2AAA

  Content-Encoding : Web 服务器表明自己用了哟压缩方法( gzip,
deflate)压缩响应中之靶子。

表示解锁地址为0x5555,0x2AAAM,其中数组[0],表示属于8个flash,定义如下:

  Content-Length: Web 服务器告诉浏览器自己应的目标的长 。

图片 6

  Content-Type: Web 服务器告诉浏览器自己应的目标的类型 。

  •  CmdSet

二、CGI

使用啊种命令,一般CmdSet=0xFFF0

  CGI ( Common Gateway Interface ,通用网关接口)是 HTTP
协议中极其根本之技艺有,有着不可替代的显要位置 。 CGI 是一个 Web
服务器提供信息服务之标准接口 。 通过 CGI 接口, Web
服务器即能够取得客户端提交的信息,转交给服务器端的 CGI
程序进行拍卖,最后回到结果让客户端 。 组成 CGI 通信系统的凡鲜片:
一部分凡 HTML
页面,就是当用户端浏览器上出示的页面;另一样组成部分则是运行在服务器上之 CG I
程序 。

  • .NumEraseRegions= 1

  浏览器就待指定执行服务器上的谁CGI程序就算推行,一般景象下,服务器和
CGI
程序中是经过正式输入输出来进展多少传递的(就如tinyhttpd中调用CGI程序),而以此历程要环境变茸的搭档方可实现。环境变量在
CGI 中有着重要之身份,每个 CGI
程序只能处理一个用户要,所以在激活一个CGI程序进程时为创造了属该过程的环境变量,CGI程序会用Python、PERL、Shell、C或C++等语言来兑现。

偏偏来1独例外的扇区区域

  CGI 环境变量在 CGI 程序启动时初始化,在竣工时销毁。当一个 CGI
程序不是吃 HTTP 服务器调用时,它的环境变盘几乎是系统环境变量的复制
。当是 CGI 程序为 HTTP 服务器调用时,它的环境变量就见面多了以下关于HTTP
服务器、客户端、 CGI 传输过程等档次。CGI 相关的环境变量有 3
种:与请求相关的环境变量、与服务器相关的环境变量和和客户端相关的环境变量,,详细呈现表
12-1 。

  • ERASEINFO(0x10000, 64)

  图片 7

共有64独扇区,每个扇区都是64KB(0x10000)

  CGI 工作原理:每当客户要 CGI 的下 Web
服务器即告操作系统生成一个初的CGI
进程,该过程处理完要后脱离,下一个求来常常更创新历程 。
当然,这样以访问量很少没有起的情形使得,可是当访问量增大且并发存在时时,这种方法就未适合了,于是就发生了FastCGI。

cfi

  一般情形下, FastCGI 的一体工作流程如下所陈述。

就以这些参数保存于cfi模式下指定地点被,
往nor的0x55地点写入0x98,即可进入cfi模式,

  ( 1 ) Web Server 启动时载入 FastCGI 进程管理器( IIS ISAPI 或 Apache
Module ) 。

cfi模式有令如下图所示:

  ( 2 )FastCGI 进程管理器自身初始化,启动多只 CGI 进程并等候来自 Web
服务器的连接 。

 图片 8

  ( 3 )当客户端请求到达 Web Server 时, FastCGI
进程管理器选择并连到一个 FastCGI进程 。 Web 服务器将 CGI
环境变量和正式输入发送至 FastCGI 进程 。

当我们于cfi模式下,比如:读取nor地址0x27处之数据,便可知读到nor的容量

  ( 4) FastCGI 子进程就处理后以正式输出及错误信息从同连接返回 Web
Server。当FastCGI 子进程关闭连接时,请求虽被告知处理完了 。 FastCGI
进程就等待并拍卖来自FastCGI 进程管理器(运行在 Web
服务器中)的下一个连接 。

一般来说图所示,之所以地址*2,是因为nor地址线A0接在咱们2440底A1达(退出cfi模式,使用复位命令即可)

三、tinyhttpd解析

图片 9

  关于tinyhttpd的代码解析的博客太多了,流程与注释都讲述的不行详细,随便搜个tinyhttpd解析就时有发生不少博客出现,这里要写一下要好在拘留即卖源码时缺少的知识点,因为我几乎无linux下编程的阅历,所以针对linux下用的Glib库调用不顶熟悉,TCP协议栈也是自个儿独自拘留了过轻量级Lwip的源码。

读到0X15,0x15=21,如下图,刚好对应我们原理图的21干净nor地址线,所以容量也2^21=2MB

  1.bind函数当传入的port为0时是碰头随随便便分配一个端口号,所以tinyhttpd中才见面起展示随机的捧口号,getsockname函数获取套接字之地方将动态分配的端口号值取出。

 图片 10

  图片 11图片 12

2.3胡上图的A20滋生脚没接通?

  2.int stat(const char *file_name, struct stat
*buf);通过文件名filename获取文件信息,并保留于buf所依赖的结构体stat中,S_IXUSR:文件所有者拥有可尽权,S_IXGRP:用户组具可实行权,S_IXOTH:其他用户具可读博权限。

对2440来讲话,因为这的A0~A19底容量刚好也2MB,与cfi模式下读取的数目一致,所以无接A20

图片 13

 

  3.int pipe(int filedes[2]);

3.接下来便来分析如何勾勒norflash驱动

  返回值:成功,返回0,否则回-1。参数数组包含pipe使用的有数单文本的叙述称。fd[0]:读管道,fd[1]:写管道。

3.1
先来回顾下前的nandflsh驱动:

  必须于fork()中调用pipe(),否则子进程不会见持续文件讲述吻合。两单过程不同步享祖先进程,就非克用pipe。但是可利用命名管道。

nandflsh驱动会放在内核的mtd设备受到,而mtd设备接头哪些通过命令/地址/数据来操作nandflash,所以我们事先的nandflash驱动只兑现了硬件相关的操作(构造mtd_info,nand_chip结构体、启动nand控制器等)

  pipe(cgi_output)执行成功后,cgi_output[0]:读通道
cgi_output[1]:写通道

同一地,norflash驱动也是放在内核的mtd设备遭遇,mtd设备也明白对nor如何来读写擦除,只是不理解norflash的位宽(数据线个数),基地址等,所以我们的norflash驱动同样要落实硬件相关的操作,供给mtd设备调用

  图片 14

 

   int dup2(int oldfd,int newfd);函数的作用是复制文件讲述称。

3.2参考内核自带的nor驱动:drivers/mtd/maps/physmap.c

  4.fork函数,创建一个子历程,fork函数之后的有的是因为以fork函数执行完毕后,如果创建新过程成功,则出现零星独过程,一个是子进程,一个是大人进程。在分进程被,fork函数返回0,在大进程中,fork返回新创建子进程的过程ID,有工夫又看fork源码是何等贯彻的。

进去其的init函数:

  5.execl函数履,第一参数path字符指针所负于如实践之文书路径,后面就可易参数,这里说一些是因为GCC使用AAPCS规范,可更换参数的实现小于四只之言语是于r0-r3获得,大于四个的说话就是使打栈中获取参数。 

 图片 15

  6.pid_t waitpid(pid_t pid, int * status, int
options);会少已目前经过的履, 直到闹信号到或子进程结束. 

发觉报了一定量只platform平台设备驱动,进入physmap_flash结构体中:

  于编写博客边看tinyhttpd,目前好的不够懂的函数就地方几乎个,有空再望它的源码实现。

 图片 16

 

发觉3独无定义的变量:

  

CONFIG_MTD_PHYSMAP_BANKWIDTH:
nandflash的配节位宽

  

CONFIG_MTD_PHYSMAP_START:nandflash的物理基地址

CONFIG_MTD_PHYSMAP_LEN:
nandflash的容量长度

立刻3个变量是由此linux的menuconfig菜单配置出的,若自己填写入值,就无欲为此menuconfig菜单配置了

 

3.3搭下去我们就来布局基本,然后挂载这个本自带的norflash驱动实验一番

3.4 首先make
menuconfig,配置方面3单变量,然后设为模块

-> Device
Drivers                

 -> Memory Technology Device (MTD)
support  

 -> Mapping drivers for chip
access                   //进入映射驱动


 

<M>
CFI Flash device in physical memory map       
  //将支持cfi的norflash设置也模块

  •    (0x0)
    Physical start address of flash mapping  // 设置物理基地址
  •   
    (0x1000000) Physical length of flash mapping  //
    设置容量长度,必须高于等于我nor的2MB
  •    (2)  
    Bank width in octets (NEW)                   //
    设置字节位宽,因为nor为16各,所以当2

 


3.5 make modules 编译模块

如下图所示,可以看看physmap.c编译成.ko模块了

 图片 17

3.6
然后在nfs目录下,启动开发板

如下图所示,insmod后打印了一样串信息:

 图片 18

正如图所示,可以观看创建了2独mtd0字符设备,一个mtd0块设备:

 图片 19

 

4.接下来我们即便分析physmap.c,如何勾勒起norflash驱动之

中physmap.c的probe函数如下

struct physmap_flash_info {
       struct mtd_info             *mtd;             //实现对flash的读写擦除等操作
       struct map_info            map;              //存放硬件相关的结构体
       struct resource             *res;
#ifdef CONFIG_MTD_PARTITIONS
       int                 nr_parts;
       struct mtd_partition      *parts;
#endif
};

static const char *rom_probe_types[] = { "cfi_probe", "jedec_probe", "map_rom", NULL };    //芯片名称

... ...
static int physmap_flash_probe(struct platform_device *dev)
{
       const char **probe_type;
       ... ...
       /*1. 分配结构体*/
       info = kzalloc(sizeof(struct physmap_flash_info), GFP_KERNEL);

       /*2.设置map_info 结构体*/
    info->map.name = dev->dev.bus_id;                 //norflash的名字
       info->map.phys = dev->resource->start;          //物理基地址
       info->map.size = dev->resource->end - dev->resource->start + 1;       //容量长度
       info->map.bankwidth = physmap_data->width;                     //字节位宽
       info->map.virt = ioremap(info->map.phys, info->map.size);    //虚拟地址

       simple_map_init(&info->map);                   //简单初始化map_info的其它成员

       probe_type = rom_probe_types;
       /*3. 设置mtd_info 结构体 */
       /*通过probe_type指向的名称来识别芯片,当do_map_probe()函数返回NULL表示没找到*/
       /*当找到对应的芯片mtd_info结构体,便返回给当前的info->mtd */
       for (; info->mtd == NULL && *probe_type != NULL; probe_type++)       
       info->mtd = do_map_probe(*probe_type, &info->map); //通过do_map_probe ()来识别芯片


       if (info->mtd == NULL) {             //最终还是没找到芯片,便注销之前注册的东西并退出
              dev_err(&dev->dev, "map_probe failed\n");
              err = -ENXIO;
              goto err_out;
       }

       info->mtd->owner = THIS_MODULE;        



       /*4.添加mtd设备*/

       add_mtd_device(info->mtd);              

       return 0;



err_out:

       physmap_flash_remove(dev);                      //该函数用来注销之前注册的东西

       return err;

}

 

由此上面的代码和注释分析及,和咱们上等同节的nandflash驱动相似,这里是装map_info
结构体和mtd_info结构体来完成的,当我们如果针对norflash分区即将用add_mtd_partitions()才行

其中当*probe_type==“cfi_probe”时:

纵使会见经do_map_probe(“cfi_probe”,
&info->map)来甄别芯片.

终极会跻身drivers/mtd/chips/cfi_probe.c中的cfi_probe_chip()函数来上cfi模式,读取芯片信息

当*probe_type==”jedec_probe”时:

末了会进去drivers/mtd/chips/jedec_probe.c中的jedec_probe_chip
()函数来运读ID命令,通过ID来配合配jedec_table[]数组.

之所以注册一个块设备驱动,需要以下步骤:

  • 1.
    分配mtd_info结构体和map_info结构体
    1. 设置map_info
      结构体
    1. 设置mtd_info
      结构体
  • 4.
    使用add_mtd_partitions()或者add_mtd_device()来创建MTD字符/块
    设备

 

5.接下来我们来参考physmap.c来协调写norflah驱动

代码如下:

#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
#include <linux/mtd/partitions.h>
#include <asm/io.h>


static struct mtd_info        *mynor_mtd_info;
static struct map_info         *mynor_map_info;


static struct mtd_partition mynor_partitions[] = {
       [0] = {
        .name   = "bootloader",
        .size   = 0x00040000,
        .offset     = 0,
       },
       [1] = {
        .name   = "root",
        .offset = MTDPART_OFS_APPEND,
        .size   = MTDPART_SIZ_FULL,
       }
};

static const char *mynor_probe_types[] = { "cfi_probe", "jedec_probe",NULL};


static int mynor_init(void)
{
    int val;

/*1. 分配map_info 结构体和mtd_info结构体*/
    mynor_mtd_info=kzalloc(sizeof(struct mtd_info), GFP_KERNEL);
    mynor_map_info=kzalloc(sizeof(struct map_info), GFP_KERNEL);

/*2. 设置map_info 结构体*/
    mynor_map_info->name="my_nor";
    mynor_map_info->phys=0x0;                          //物理地址
    mynor_map_info->size=0x1000000;                 //=16M,长度必须大于等于norflash的2M容量
    mynor_map_info->bankwidth=2;                     //16位宽
    mynor_map_info->virt = ioremap(0x0, mynor_map_info->size);   //虚拟地址
    simple_map_init(mynor_map_info);

/*3. 设置mtd_info 结构体*/
   mynor_mtd_info = do_map_probe("cfi_probe", mynor_map_info);
   if (!mynor_mtd_info)
   {
     mynor_mtd_info = do_map_probe("jedec_probe", mynor_map_info);
    }

    if (!mynor_mtd_info)
    {
    printk(“not available norflash !!!\r\n”);
    goto err_out;
    }
    mynor_mtd_info->owner=THIS_MODULE;

 

/*4. 使用add_mtd_partitions()或者add_mtd_device()来创建MTD字符/块 设备*/
       add_mtd_partitions(mynor_mtd_info,mynor_partitions,2);
       return 0;


err_out:
       iounmap(mynor_map_info->virt);                      //取消虚拟地址映射
       kfree(mynor_map_info);
       kfree(mynor_mtd_info);      
       return 0;
}


static  void mynor_exit(void)
{
    del_mtd_partitions(mynor_mtd_info);                  //卸载分区
    iounmap(mynor_map_info->virt);                      //取消虚拟地址映射
    kfree(mynor_map_info);
    kfree(mynor_mtd_info);       
}

module_init(mynor_init);
module_exit(mynor_exit);
MODULE_LICENSE("GPL");

 

6.挂载驱动试验

(一定要于nor启动下挂载才行,因为2440应用nand启动时,是看不了nor的前4k地址)

insmod挂载驱动后,如下图所示:

 图片 20

得看到创建了少数只分区“bootloader”,“root”,如下图所著,可以看看创建了2针对性mtd字符/块设备

 图片 21

6.1
接下便来对root分区(mtd1)来试(使用flash之前最好好擦除同糟糕)

步骤如下:

./flash_eraseall -j /dev/mtd1                      //使用mtd-util工具的flash_eraseal命令来擦除root分区(mtd1)

mount -t jffs2 /dev/mtdblock1 /mnt/                //使用mount挂载文件系统, -t:文件系统类型(type)

 

联网下就是足以当/mnt目录下来任意读写文件了,最终会保留于flash的mtdblock1块装备受到

(PS:可以参考内核自带的mtdram.c,里面是运用外存来模拟flash,
里面通过memcopy()等来贯彻对内存读写擦除)

相关文章