微信号:grzlwx

介绍:光荣之路官方资讯

【扫盲】从输入 URL 到页面加载完成,都发生了什么事情?(之一)

2015-10-03 13:46 光荣之路

大家可曾思考过,从输入网络地址到你看到网页,这中间都发生了些什么?我们将从下面几个阶段分六期来讨论。如果有兴趣,可以扩展阅读和深入研究一下。

第一:从输入 URL 到浏览器接收的过程中发生了什么事情

第二:浏览器如何向网卡发送数据

第三:数据如何从本机网卡发送到服务器

第四:服务器接收到数据后会进行哪些处理

第五:服务器返回数据后浏览器如何处理

第六:浏览器如何将页面展现出来


第一个问题:从输入 URL 到浏览器接收的过程中发生了什么事情?


从触屏到 CPU


首先是「输入 URL」,大部分人的第一反应会是键盘,不过为了与时俱进,这里将介绍触摸屏设备的交互。


触摸屏一种传感器,目前大多是基于电容(Capacitive)来实现的,以前都是直接覆盖在显示屏上的,不过最近出现了 3 种嵌入到显示屏中的技术,第一种是 iPhone 5 的 In-cell,它能减小了 0.5 毫米的厚度,第二种是三星使用的 On-cell 技术,第三种是国内厂商喜欢用的 OGS 全贴合技术。


当手指在这个传感器上触摸时,有些电子会传递到手上,从而导致该区域的电压变化,触摸屏控制器芯片根据这个变化就能计算出所触摸的位置,然后通过总线接口将信号传到 CPU 的引脚上。


以 Nexus 5 为例,它所使用的触屏控制器是 Synaptics S3350B,总线接口为 I²C,以下是 Synaptics 触摸屏和处理器连接的示例:



左边是处理器,右边是触摸屏控制器,中间的 SDA 和 SCL 连线就是 I²C 总线接口。


CPU 内部的处理


移动设备中的 CPU 并不是一个单独的芯片,而是和 GPU 等芯片集成在一起,被称为 SoC(片上系统)。


前面提到了触屏和 CPU 的连接,这个连接和大部分计算机内部的连接一样,都是通过电气信号来进行通信的,也就是电压高低的变化,如下面的时序图:



在时钟的控制下,这些电流会经过 MOSFET 晶体管,晶体管中包含 N 型半导体和 P 型半导体,通过电压就能控制线路开闭,然后这些 MOSFET 构成了 CMOS,接着再由 CMOS 实现「与」「或」「非」等逻辑电路门,最后由逻辑电路门上就能实现加法、位移等计算,整体如下图所示(来自《计算机体系结构》):



除了计算,在 CPU 中还需要存储单元来加载和存储数据,这个存储单元一般通过触发器(Flip-flop)来实现,称为寄存器。


以上这些概念都比较抽象,推荐阅读「How to Build an 8-Bit Computer」这篇文章,作者基于晶体管、二极管、电容等原件制作了一个 8 位的计算机,支持简单汇编指令和结果输出,虽然现代 CPU 的实现要比这个复杂得多,但基本原理还是一样的。


另外其实我也是刚开始学习 CPU 芯片的实现,所以就不在这误人子弟了,感兴趣的读者请阅读本节后面推荐的书籍。


从 CPU 到操作系统内核


前面说到触屏控制器将电气信号发送到 CPU 对应的引脚上,接着就会触发 CPU 的中断机制,以 Linux 为例,每个外部设备都有一标识符,称为中断请求(IRQ)号,可以通过 /proc/interrupts 文件来查看系统中所有设备的中断请求号,以下是 Nexus 7 (2013) 的部分结果:


shell@flo:/ $ cat /proc/interrupts

CPU0

17: 0 GIC dg_timer

294: 1973609 msmgpio elan-ktf3k

314: 679 msmgpio KEY_POWER


因为 Nexus 7 使用了 ELAN 的触屏控制器,所以结果中的 elan-ktf3k 就是触屏的中断请求信息,其中 294 是中断号,1973609 是触发的次数(手指单击时会产生两次中断,但滑动时会产生上百次中断)。


为了简化这里不考虑优先级问题,以 ARMv7 架构的处理器为例,当中断发生时,CPU 会停下当前运行的程序,保存当前执行状态(如 PC 值),进入 IRQ 状态),然后跳转到对应的中断处理程序执行,这个程序一般由第三方内核驱动来实现,比如前面提到的 Nexus 7 的驱动源码在这里touchscreen/ektf3k.c


这个驱动程序将读取 I²C 总线中传来的位置数据,然后通过内核的 input_report_abs 等方法记录触屏按下坐标等信息,最后由内核中的 input 子模块将这些信息都写进 /dev/input/event0 这个设备文件中,比如下面展示了一次触摸事件所产生的信息:


130|shell@flo:/ $ getevent -lt /dev/input/event0

[ 414624.658986] EV_ABS ABS_MT_TRACKING_ID 0000835c

[ 414624.659017] EV_ABS ABS_MT_TOUCH_MAJOR 0000000b

[ 414624.659047] EV_ABS ABS_MT_PRESSURE 0000001d

[ 414624.659047] EV_ABS ABS_MT_POSITION_X 000003f0

[ 414624.659078] EV_ABS ABS_MT_POSITION_Y 00000588

[ 414624.659078] EV_SYN SYN_REPORT 00000000

[ 414624.699239] EV_ABS ABS_MT_TRACKING_ID f f f f f f f f

[ 414624.699270] EV_SYN SYN_REPORT 00000000


从操作系统 GUI 到浏览器


前面提到 Linux 内核已经完成了对硬件的抽象,其它程序只需要通过监听 /dev/input/event0 文件的变化就能知道用户进行了哪些触摸操作,不过如果每个程序都这么做实在太麻烦了,所以在图像操作系统中都会包含 GUI 框架来方便应用程序开发,比如 Linux 下著名的 X


但 Android 并没有使用 X,而是自己实现了一套 GUI 框架,其中有个 EventHub 的服务会通过 epoll方式监听 /dev/input/ 目录下的文件,然后将这些信息传递到 Android 的窗口管理服务(WindowManagerService)中,它会根据位置信息来查找相应的 app,然后调用其中的监听函数(如 onTouch 等)。


就这样,我们解答了第一个问题,不过由于时间有限,这里省略了很多细节,想进一步学习的读者推荐阅读以下书籍。


扩展学习


  • 《计算机体系结构》

  • 《计算机体系结构:量化研究方法》

  • 《计算机组成与设计:硬件/软件接口》

  • 《编码》

  • 《CPU自制入门》

  • 《操作系统概念》

  • 《ARMv7-AR 体系结构参考手册》

  • 《Linux内核设计与实现》

  • 《精通Linux设备驱动程序开发

(网摘)

更多测试咨询和招聘信息,请关注光荣之路微信公众号:gloryroadtrain


 
光荣之路 更多文章 今天晚上的 linux 公开课- Awk 编程 7月28日(今天)晚上的 linux 公开课- shell编程 8月4日(今天)晚上的 linux 公开课- shell编程 9月1日(本周一)晚8点半,光荣之路Web自动化系列基础课—javascript第二讲 推荐本好书《与机器赛跑》
猜您喜欢 iOS开发中可以节省50%编译等待时间的几个措施 FAQ系列 | 不同复制模式下,如何忽略某些binlog事件 要测试却没有测试机?那都不是事儿! 美女与程序员共处电梯 脑洞大开 所有业务全部容器化,谈知乎的Docker实践之路