分区操作系统(Partition Operating System)概述

本文概述:随着嵌入式系统日趋复杂化以及对安全性要求的不断提高,采用空间隔离、时间预先分配的分时分区操作系统已经成为未来的发展方向。本文描述分时分区操作系统出现的背景、实现技术、以及设计理念,来研究主流的基于分离内核(Separation Kernel)的分区系统的设计与实现机制。由于本文专注于嵌入式实时系统领域,因此这里的分区系统和分区实时系统不做严格的区分,均指基于分离内核架构的分区系统。

1.1 什么是分区操作系统

分区(Partitioning)的概念首先由John Rushby于1999年[1]首次提出,其定义为“The purpose of partitioning is fault containment: a failure in one partition must not propagate to cause failure in another partition.”。中文的意思是“分区的目的是容错:一个分区中的故障不能传递给其它分区,并导致其它分区故障.”

Rushby给分区定义了两个非常重要的属性,即空间隔离和时间隔离:

空间隔离:分区必须保证一个分区的软件不会改变另外一个分区的软件,或者修改另外分区软件的数据;

时间隔离:分区必须确保一个分区中的软件所接收到的共享资源的服务不会影响到另外一个分区中使用该共享资源的软件。

分区操作系统标准的定义是既通过分区的概念实现了应用之间的时空域隔离,达到容错和简化验证的目的;又通过采用为不同分区设定不同的安全级别的多级安全(MLS,Multi-Level Security)架构,为系统提供安全性和可靠性的基础支撑,避免操作系统中访问控制机制被篡改、绕过,使得各个安全关键任务独立运行,通过受控的消息机制进行交互,有效保证了各个应用和各部分数据的独立安全性。

这个概念对于初次接触分区操作系统的读者可能会有点晦涩,我举个例子来说明。在中国古代有一家三兄弟全是郎中。其中老三是名医,人们问他:“你们兄弟三人谁的医术最高?”他回答说:“我常用猛药给病危者医治,偶尔有些病危者被我救活,于是我的医术远近闻名并成了名医。我二哥通常在人们刚刚生病的时候马上就治愈他们,临近村庄的人说他是好郎中。我大哥不外出治病,他深知人们生病的原因,所以能够预防家里人生病,他的医术只有我们家里才知道。”分区操作系统类似于这个郎中家庭中的老二,它不能避免系统中的应用发生故障,而是在应用发生故障的时候,对故障进行处理,使其不会影响到系统中其它组件的正常运行。

备注:老大治病的方式最高明,如果使人们能够预防生病的话,那么没病就用不着看医生了。它类似于在系统开发过程中防止产生缺陷,将高质量内建于软件开发过程之中。主要措施是“不断地提高技术水平,不断地提高规范化水平”,这方面的典型是航空领域的DO178B/C开发标准,由于本文侧重于分区操作系统软件架构,因此软件开发规范则不是本文描述的重点。

分区实时操作系统最重要的特性是可靠性,可靠性是指系统在异常的条件下,仍然能够工作的能力。软件的可靠性和正确性不同,后者是描述软件在需求范围之内的行为,而前者是描述软件在需求范围之外的行为。但是正常情况和异常情况并不容易区分,软件开发者往往要么没有想到异常情况,要么把异常情况当做正常情况而不做处理,从而降低了软件的可靠性。

可靠性有两层含义:容错能力和恢复能力。容错能力是指应用发生故障情况时,系统不出错的能力,对于应用于航空航天、武器、金融领域的这类高风险系统,容错设计非常重要;分区实时系统最重要的特性就是容错性,恢复能力是指软件发生故障后(不论死活),重新运行后恢复到没有发生故障前的状态的能力;从语义上来说,恢复不及容错那么健壮。举个例子:某个人挨了坏蛋的一顿拳脚,特别健壮的人一点事儿都没有,表示容错能力强;比较健壮的人,虽然被打倒在地,过了一会还能爬起来,除了皮肉之痛外,倒也不用去医院,表示恢复能力比较强;而虚弱的人可能短期恢复不过来,得在病床上躺很久。

恢复能力也是很有价值的,Microsoft公司早期的视窗系统,比如Windows 3.x和Windows 9x,动辄死机,其容错性比较差,但它们的恢复能力还是不错的,机器重启后,一般都能够正常运行,看在这个份上,人们还是愿意将就着用。

分区实时系统设计的目标是在在保证系统可靠性的前提下,使其具有传统RTOS一样的确定性,即在构架和设计模式上对系统进行重新设计,而不在无关痛痒的地方瞎忙活。分区实时系统强调容错方面的Safety安全性,虽然英文中Security在汉语中也是安全,但Security安全是指防止系统被非法入侵的能力,既属于技术问题,也属于管理问题,这个词侧重于信息安全。信息安全是一门深奥的学问,其发展是建立在正义与邪恶的斗争之上的。这个世界并不存在绝对的安全系统,连美国军方的系统都频频遭黑客入侵,如今全球黑客泛滥,犹如“道高一尺魔高一丈”。但是从嵌入式系统发展历程来看,受限于早期嵌入式CPU芯片设计水平,早期的嵌入式系统侧重于系统功能和性能,随着嵌入式CPU性能的提高,人们在此基础上加入的Safety安全性,近年来随着移动互联网的普及,Security安全越来越受到人们的关注,这也是基于分区架构的操作系统越来越受到人们的重视原因。

1.2 分区操作系统出现背景

分区操作系统是嵌入式CPU设计水平发展到一定程度的结果,应用于嵌入式领域的CPU发展水平可以分为4个阶段。

第1阶段:单片微型计算机(SCM: Single Chip Micyoco)阶段,即单片机时代。这一阶段的嵌入式系统硬件是单片机,软件停留在无操作系统阶段,采用汇编语言实现系统的功能。这阶段的主要特点是:系统结构和功能相对单一、处理效率低、存储容量也十分有限,几乎没有用户接口,运行在SCM上的应用往往是一个封闭的应用,只需要完成用户需求的功能即可,没有安全性方面的现实需求。

第2阶段:微控制器(MCU: Micro Controller Unit)阶段。主要技术发展方向是:不断扩展对象系统要求的各种外围电路和接口电路,突显其对象的智能化控制能力。这一阶段主要以嵌入式微处理器为基础、以简单操作系统为核心,主要特点是硬件使用嵌入式微处理器,微处理器的种类繁多,通用性比较弱;系统开销小,效率高。这个阶段CPU只有一种运行模式,与之配套的系统比如uC/OS,FreeRTOS等实时多任务系统,但硬件上仍无法支撑系统安全性的需求,此类实时系统强调系统的功能和性能。

第3阶段:片上系统(SOC)。嵌入式系统能够运行于各种不同类型的微处理器上,兼容性好,操作系统的内核小,效果好。比如基于ARM架构的s3c2440,s3c2410,与之配套的系统比如VxWorks系统。

这类CPU至少具有用户模式/系统模式两种运行状态。但是运行在上面的RTOS,比如VxWorks只在系统模式下运行,虽然系统性能得到了保证,但是没有利用处理器提供用户模式/系统模式两种运行状态、以及硬件MMU,因此仍然缺少Safety安全特性。

第4阶段:随着制造技术的进步,以及嵌入式网络化方面的需求。嵌入式处理器的性能也接近或者达到PC处理器的性能。比如恩智浦的MPC8640D双核处理器采用PowerPC E600内核,单核主频可以达到1.5GHz,具有为嵌入式网络、电信、航空航天与国防、存储、工业和普适计算等诸多应用带来突破性的性能、连接特性和集成度。嵌入式CPU性能高速发展,完全满足一种新的软件系统架构,其利用处理器的不同运行模式,以及硬件MMU机制在实现系统自身安全性的同时,也可以满足用户对性能的需求。在这种条件下,分区系统应运而生。分区系统的先行者是运行在航空电子领域的IMA系统,其早在1997年便提出了ARINC653标准,为IMA的需求进行了定义,提出了基于时空域的分区系统。

从嵌入式软件的发展历程来说,其经历了前后台系统、实时系统、和分区系统三个阶段。

前后台系统(Foreground/Background System)其实没有操作系统,系统中只运行一个无限主循环,没有多任务的概念,但是通过中断服务程序响应外部事件。在前后台系统中,对外部事件的实时响应特性应从两方面来看:

中断延迟时间:主循环一般保持中断开放状态,因此前后台系统的中断响应非常快,并且通常允许嵌套,中断延迟时间特别短;

中断响应时间:需要经历一次主循环才能对中断服务程序中采集的外部请求进行处理,因此系统响应时间决定于主循环周期。

实时操作系统(RTOS)的目的是实现对外部事件的实时响应,即在确定的时间内给出响应。实时操作系统必须满足下面4个条件:

1)  可抢占式的优先级调度内核,当一个运行着的任务使一个比它优先级高的任务进入了就绪态,当前任务的CPU 使用权就被剥夺了,或者说被挂起了,那个高优先级的任务立刻得到了CPU的控制权,即始终保证优先级最高的任务拥有CPU使用权;

2)  中断具有优先级,且中断可嵌套,即高优先级的中断可以打断正在执行的低优先级中断处理程序,优先得到执行,等到其处理完毕再回到低优先级的任务继续执行;

3)  防止优先级反转;

4)  实时操作系统(RTOS)的性能评价指标(中断响应时间和任务切换时间)具有固定上界。

早期的实时系统局限于处理器计算能力的限制,设计的重点在于保证系统功能的前提下,尽可能的提高系统的性能。因此,实时系统的设计往往采取单一实地址空间模式,所有任务在同一地址空间运行,不区分核心态和用户态。其优势在于:

1)  任务切换时不需要进行虚拟地址空间切换;

2)  任务间可以直接共享变量,不需要通过内核在不同的地址空间复制数据;

3)  系统调用时不需要在核心态和用户态之间切换,相当于直接的函数调用。

从前后台系统发展到实时系统,降低了系统的响应时间;提高了系统的移植性;但是由于历史条件的局限,传统的RTOS只利用处理器的特权模式,面临着以下的不足:

1)  硬件设备的复杂性、多样性导致系统出错频繁

在现代操作系统中硬件相关代码占到很大的比重,例如Linux内核中大约70%的代码是设备驱动程序。操作系统的开发人员需要熟悉各种硬件体系结构以及外部设备特性,稍有不慎将导致系统崩溃。斯坦福大学的一项研究表明Linux设备驱动缺陷出现的频率比内核的其它部分高出5~7倍以上。另外就VxWorks-5.5而言,其内核稳定性在业界有口皆碑,但是随着硬件平台及外设的不断丰富,在VxWorks-5.5的USB驱动中出现的错误将直接影响到vxWorks-5.5产品的稳定性。

2)  高度并发处理导致严重的资源竞争

RTOS内核中面临着极为频繁的竞争行为,这样竞争行为是由任务之间、中断之间、以及任务与中断之间对各类共享资源的并发访问和可重入操作引起的,对系统的可靠性带来巨大的威胁,包括原子性破坏、数据一致性破坏、死锁、优先级翻转等。据统计,由竞争引发的错误在RTOS内核中出现的比例远高于其他软件。

3)  由于并行、时序原因引发的错误导致系统故障定位困难

相对于应用软件而言,RTOS的错误定位难度要高得多。一方面,由于RTOS是整个系统的最底层软件,缺乏其它的软件作为运行支撑,因此对其调试和测试都需要定制的工具才可以完成;另一方面由于RTOS运行的高度并发性、时序相关性导致其错误不易被发现、错误重现难度极大。因此在RTOS设计中如何嵌入观测代码、以便有效采集系统运行状态及相关数据,以便重现系统运行错误现场和运行过程,将显得极为重要。

4)  隔离和包含手段仍显薄弱

各个应用程序在保障自身运行正确性和安全性外,还需要防止在其它模块发生错误之后可以不受错误级联反应的影响。因此需要RTOS提供一套有效的隔离与保护机制来限制错误的扩散和蔓延。现有的隔离和保护手段主要是借助于MMU和MPU对地址空间进行保护,存在保护力度大、资源消耗多、性能影响大等缺陷,仍缺乏一套有效的软硬件结合的隔离手段与机制。

但是随着处理器性能的提高,以及互联网的出现;如何在保证系统功能和性能的同时,具有Safety和Security上的安全性,越发显得十分重要。尤其近年来嵌入式领域多核处理器的广泛应用,支持多核的分区系统可以通过内核来配置分区支持AMP和SMP方式,在保证系统吞吐量和响应时间的同时,具有Safety和Security上的安全性,因此具有巨大的技术优势。

1.3 分区操作系统技术实现

分区操作系统采用嵌入式虚拟化技术实现分区隔离。虚拟化技术并不是新的技术,早在20世纪60年代,虚拟化技术就已经应用于大型机系统。然而直到20世纪90年代中期,桌面处理器技术的提升才真正开启了虚拟机技术在PC上的应用,嵌入式市场也由此开始利用这一个非常有前景的技术。从虚拟机使用资源角度来看,虚拟机可以划分成两类:Type-I虚拟机与Type-II虚拟机,如图1所示。Type-I虚拟机直接运行在裸的硬件上,故称之为裸机虚拟机或者本地虚拟机;Type-II虚拟机运行在一个操作系统上面,比如VMware,Virtual box等等。运行在裸机上的操作系统称为主机操作系统(Host OS),运行在虚拟机上的操作系统,称为客户操作系统(Guest OS)。

分区操作系统(Partition Operating System)概述

图1 Type-I和Type-II虚拟机架构

分区操作系统采用Type-I虚拟机技术实现分区的时空隔离,这里需要指出的是分区系统和Type-II虚拟机虽然技术上有重合,但是在理念上(或者说追求的目标)上还是有所区别的,在嵌入式领域虚拟化技术(Type-I Hypervisor技术)是实现分区(时空域隔离)的一种手段,目前分成两个发展方向:一个侧重于Safety安全,以实现一个容错系统(Fault Tolerate System),比较典型的是实现航空ARINC 653标准的系统,比如VxWorks653、Integrity178B RTOS;另一个侧重于Security安全,侧重于信息安全、防黑客攻击。典型的是实现MILS架构,比如VxWorks MILS,Lynx-Secure等。两者也存在 交集,因此本文描述的分区系统,侧重于实现一个基本的时空域隔离系统,然后通过不同的功能扩展,来满足Safety或者Security的应用要求。

我们把采用Type-I Hypervisor技术实现的分区系统内核也称为分离内核(Separtation Kernel)架构,如图2所示。

分区操作系统(Partition Operating System)概述

图2 分离内核(Separtion Kernel)架构

分离内核架构的操作系统采用分区(Partition)的概念隔离硬件资源、系统软件、以及用户应用,并严格控制硬件组件和不同分区应用的信息流,以实现整个系统的Safety安全性和Security安全性。

1.4 分区系统的研究现状

嵌入式虚拟化技术在航空领域和车载系统领域已经应用的非常成熟,在航空领域针对IMA(Integrated Modular Avionics) 综合模块化航电系统体系结构的发展趋势,从1997年开始美国就制定了航空电子应用软件标准接口ARINC653标准规范,为IMA的需求进行了定义,提出了基于时空域的分区系统设计思想,并明确定义了应用软件与操作系统、操作系统与底层硬件的接口标准。满足ARINC653标准的Partition实时系统,实现了各个应用之间的时间和空间隔离,使得分配给一个分区的执行时间不会因为其它分区的超时运行或者事件出错而有所改变,一个分区出现故障也不会影响到其它分区的运行。分区是一个独立的应用环境,由数据、上下文关系、配置属性和其它项组成,分区的运行满足了时间和空间要求。因而分区具有故障隔离和故障恢复的能力。

分区架构的操作系统在车载也有着广泛的应用,信息技术的飞速发展同样也带动了汽车产业的电子化,日益复杂的功能促使汽车电子软件的开发朝着大型化和复杂化方向发展。为实现汽车电子软件的可移植性和兼容性,德国汽车工业界于1993 年推出汽车电子开放式系统以及接口(OSEK)标准。法国汽车行业紧随其后,于1994 年推出相似的汽车分布式执行规范(Vehicle Distributed Executive,VDX),并与OSEK 规范合并,形成了OSEK/ VDX[2]规范。该规范致力于为汽车分布控制单元提供一个开放结构的工业规范,目前已成为嵌入式汽车电子软件开发的通用标准。

2003年,由汽车电子软件标准联盟制定的汽车开放系统架构AUTOSAR(AUTomotive Open System Architecture)联盟成立,以OSEK/VDK 规范为基础提出了一整套汽车电子软件开发方法和软件架构标准化方案。AUTOSAR[3] 规范旨在为汽车电子软件开发领域提供开放的、标准化的软件架构,以及一个标准的软件运行时环境(Runtime Environment, RTE)界面,使得软件运行独立于硬件平台之外,从而促进软件复用和集成,缩短软件开发周期,提升整个汽车行业的效率。自2005 年AUTOSAR 规范1.0 版本发布以来,截止到目前已发布4.2版本。AUTOSAR 规范包含3个部分内容:软件架构(AUTOSAR architecture),方法论(AUTOSAR methodology)和应用接口(AUTOSAR application interfaces)。其中AUTOSAR操作系统规范属于软件架构部分的内容。

AUTOSAR(AUTomotive Open System Architecture)在操作系统的需求说明(Requirements on Operating System V4.2)中明确规定了车载操作系统采用Partition-RTOS结构。并指出分区必须具有故障隔离和故障恢复的能力,同时分区具有内存保护功能,阻止一个分区的应用修改另一个分区的内存。

目前主流的操作系统厂商,主要有美国的Green Hills[4]WindRiver[5]Lynx[6]、以及欧洲的SYSGO公司。他们均采用分离内核(Separation Kernal[7])的分区架构(图2所示),均通过了DO178B认证和IEC 61508 SIL认证。因此,我们可以得出一个结论:如果要设计一款具有Safety&Security安全特性的操作系统,系统至少要满足分离内核(Separation Kernel)的设计架构,而基于线程和进程的操作系统几乎是不可能达到安全要求的。

通过分区的概念来保障系统安全,主要关注的方向包括空间分区(Space Partitioning)、时间分区(Time Partitioning)、资源分区(Resource Partitioning)。分区有两个层面的含义,一个是分配(例如处理器时间片),一个是分割(例如内存空间),一般来说,资源使用权对应的是分配,资源拥有权对应的是分割,本文统一叫分区或者划分,不再详细区分。

分区系统的基本设计理念总结有四:一是隔离,二是可期,三是转移,四是管制:

1) 隔离即分而治之,各分区之间和平共处不得冲突,原则上需要共享数据的应用尽量集中在同一分区内;

2)可期即到期交回资源使用权,交由其它分区,原则上不得陷入超时等待。

3)转移即责任分配到分区内,故障自理,简化Partition-RTOS整体架构,越简单越健壮。

4)藩王之间私通书信等于谋逆,所有治外行为必须获得中央授权,受中央管制。因此原则上分区之间数据交互能省则省,可以避免授权过程的额外开销。(分区操作系统内核本身并不要求授权机制,这分离内核提供的分区间通信的IPC(Inner Partition Communication)基础上,通过分区内中间件实现。

本着以上四项设计理念,分离内核的具体实现则各RTOS供应商略有出入,主要在转移和管制两方面:

1)分区应用和Partition内核应用之间有多种接口方式,包括最基本的API模式、子操作系统模式、以及中间件。其中子操作系统和中间件的实现方式多种多样,可以转移分担传统操作系统中部分功能。例如驱动,文件系统等与分区不相关的模块,中间件可以通过内存映射、寄存器地址映射等方式把硬件资源划分给分区,允许分区独占并操作。这也是资源分区的体现方式之一。转移的原则是:分化责任,能交给分区的就交给分区,降低Partition-RTOS负担,提高Partition-RTOS的安全稳定性。这与法国著名飞行家和作家Antoine de St. Exupery的名言:“完美不是再没有什么东西可以加入,而是再没有什么东西可以去除”如出一辙。

2)分区间互访在原则上违背了隔离的理念,因此并非所有RTOS供应商都推崇。但许多军用设备提出MILS(多独立安全级别Multiple Independent Levels of Security)的需求,要求单设备支持多个独立的应用(每个应用具备独立的安全级别,互访需遵循权限高低规则),便于精简硬件,降低现场携带负担。针对MILS需求要求支持基于权限的分区间信息交互,但必须受分区内核管制。但是如果若干应用之间是数据流紧密耦合的,设计原则上仍然不推荐把这些应用分离在多个分区中互访。

1.5 分区系统的设计目标

采用分离内核的分区设计架构,是从分区隔离、降低耦合、以及增加中间层三个角度出发,来设计分区操作系统。

分区隔离:从广度上来考虑分离内核的可靠性设计,RTOS运行的基本单元是任务。而一个任务所占用的资源是内存空间和CPU时间两个方面。因此可以从这两个方面着实将内核进行隔离设计,将不同的任务放在时间和空间上已经进行隔离的分区中运行,使其互不影响。由于每个任务在各自不同的分区内运行,所有对其它任务没有干扰,从而增强了系统的可靠性。

增加中间层:英国著名计算机科学家David Wheeler增说过一句名言[8]“All problems in computer science can be solved by another level of indirection.”,意思是说计算机科学领域内的一切问题都可以通过增加一个间接的中间层来解决。增加中间层的思想,就是一种从RTOS体系结构上考虑,通过增加一个中间层来提供RTOS的可靠性。

降低耦合性:低耦合性是一种重要的设计模式思想,低耦合一方面降低了因一个模块的变化而影响到其它模块的范围;另一方面使得模块更内聚、结构更简单、可裁剪性更强、以及便于理解。在分区系统的设计中采用低耦合的思想,将有助于提高系统的可靠性。以VxWorks-5.5为例,其Wind内核包含任务管理、同步通信、内存管理等功能,这些功能往往和设备驱动内聚在一起,任何一个模块的错误都将导致系统崩溃。究其原因,RTOS内核功能模块间耦合度太高导致其可靠性降低。因此采用低耦合的思想,拆分各个功能模块,重新组织RTOS结构使其独立开来,以增强器可靠性。

总之分区系统设计的核心思想在于“隔离”,无论是采用时空域隔离的分区策略、执行隔离的中间层、还是降低耦合性的功能块隔离无不体现着这个思想。

1.6 本网站研究目标

策略(Mechanism)和机制(Policy)相分离的原则是本网站研究分区实时操作系统的指导思想,换句话说Separation Kernel仅提供可靠性机制和策略接口,而将可靠性策略的规则和方法教给Partition中的应用程序完成。为了更清楚地说明这一点,我们可以以任务调度为例。一个简单的调度算法是为每一个任务赋予一个优先级,并让内核执行具有最高优先级的就绪任务。在这个例子中,机制(Mechanism)是在内核中寻找最高优先级的就绪任务并运行之;而策略(Policy)则是赋予任务相应的优先级。换句话说机制负责提供什么样的功能,策略则负责如何使用这些功能。策略和机制相分离指导思想可以使操作系统内核变得更小,更稳定。正如我们在前面所提到的:“完美不是再没有什么东西可以加入,而是再没有什么东西可以去除”。

我们将在Separation Kernel的设计当中,按照内核层、服务层、用户层分布划分多个层次、细粒度的容错能力,并根据具体的应用背景,零活的配置和指定容错策略,使得分区系统兼具可靠性和实时性,以满足Safety和Security不同侧重点的应用需求。我将力图从一个系统设计者的角度来分析并研究Separation Kernel架构的设计思想、工作机制、以及具有的特性,并通过设计一个可以运行的原型系统来展示基于Separation Kernel架构的分区实时系统的特性,以便更多的读者可以了解国外主流的RTOS厂商提供的针对Safety和Security应用的分离内核系统产品、以及对应的解决方案。

1.7 参考链接

[1]John Rushby "Partitioning in Avionics Architectures: Requirements, Mechanisms, and Assurance," Mar.1999.

http://www.csl.sri.com/users/rushby/

[2]http://portal.osek-vdx.org

[3]http://www.autosar.org

[4]http://www.ghs.com/products.html

[5]http://www.windriver.com/products/vxworks/certification-profiles/

[6]http://www.lynx.com/products/

[7]https://en.wikipedia.org/wiki/Separation_kernel

[8]http://en.wikipedia.org/wiki/David_Wheeler_(computer_scientist)

 

PS:搭建对本文有任何疑问或者任何建议,欢迎给我留言O(∩_∩)O~....

 

目前评论:4   其中:访客  4   博主  0

  1. avatar lijie 0

    章节 1.1, “随着嵌入式CPU性能的提供”,这里的“提供”是笔误吧,应该是“提高”之类的。

  2. avatar cohan 1

    对博主的PRTOS很期待啊!

    • avatar prtos, info 2

      @cohan \(^o^)/~,最近工作太忙,暂时抽不出时间折腾,你有啥功能上的建议可以给我留言,我后续更新系统时作为一个参考。

评论加载中...

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: