ubi详解

更新时间:2024-04-03 14:26:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

UBIFS 简介

由IBM、nokia工程师Thomas Gleixner,Artem Bityutskiy等人于2006年发起,致力于开发性能卓越、扩展性高的FLASH专用文件系统,以解决当前嵌入式环境下以FLASH作为MTD设备使用时的技术瓶颈, 开发背景: FLASH特性: FLASH是一类电可擦出可编程存储体,在使用方式上与硬磁盘最大不同是: FLASH文件系统所必须的关键技术: 1. 由于FLASH的“先擦除后写”的特性决定,必须(或者说所被公认为)采用异地更新策略(out-of-place update)。相关问题讨论可参考: 2. 采用异地更新策略就必须(或者说所被公认为)采用日志文件系统来管理。 3. 采用日志文件系统就必须(或者说所被公认为)实现垃圾回收(garbage collection) 4. 由于FLASH的物理擦除块(Physical Erase Block)只有有限次有效擦除,所以必须(或者说所被公认为)采用“负载平衡”(我比较喜欢翻译为“损益均衡”——一个经济学术语)(Wear- Leveling)技术,即保证上的(几乎)所有 PEB的擦除次数趋向于均衡化,从而避免小部分PEB大大先于其他PEB而”坏“掉。 当前嵌入式FLASH解决方案多采用: 1. 无文件系统直接使用FLASH:缺点很明显 2. 采用传统文件系统,如ext2,ext3, FAT16/32, dos,Cramfs 等:这些文件系统本来是为传统的磁盘体开发的,他们无法高效的管理以FLASH作为介质的文件系统,特别是在FLASH的使用寿命上。于是出现了第3中方案。 3. 采用FTL/NFTL(flash 转换层/nand flash转换层)+ 传统文件系统:FTL的使用就是针对FLASH的特有属性,通过硬件的方式来实现日志管理、损益均衡等技术。但实践证明,由于各方面因素导致本方案有一定的局限性。 4. FLASH专用文件系统,如JFFS1/2,YAFFS等,他们从一定程度上缓解了flash使用上的技术瓶颈。但也仍然存在诸多问题:如内存消耗大,对 FLASH容量、文件系统大小、内容、访问模式等的线性依赖,损益均衡能力差活过渡损益。随作FLASH容量逐渐暴涨(我见到的资料已经有 64GFLASH已经实用化),JFFS,YAFFS几乎无法管理如此大的FLASH——虽然JFFS目前还在改进中,但前途不看好,一个很好的例子 JFFS的主要开发者大多倒向了UBIFS。:) UBI:一种类似于LVM的逻辑卷管理层。主要实现损益均衡,逻辑擦除块、卷管理,坏块管理等。 UBIFS:基于UBI的FLASH日志文件系统。 有关ubifs的详细介绍,请参考: http://www.linux-mtd.infradead.org/doc/ubi.html http://www.linux-mtd.infradead.org/doc/ubifs.html 使用UBIFS前的准备

1. 获取 ubifs: 2.6.22以后,ubifs活跃于git管理工程中 git://git.infradead.org/ubi-2.6.git 2.6.27以后,ubifs被整合进内核树中,用户只需下载最新内核即可获取ubifs支持。 2. 配置linux内核 (2.6.28 以上 kernel 已经包含 ubifs, 早期的kernel 还得去官网上找找,我的就是 2.6.28) 配置的时候选上 1)Device Drivers --->Memory Technology Device (MTD) support --->UBI - Unsorted block images --->Enable UBI

2)File systems --->Miscellaneous filesystems --->UBIFS file system support

这样我们的内核就支持UBIFS文件系统了 3. UBIFS工具 mtd-utils工具中提供了对UBIFS的支持,所以我们需要下载和编译这些工具,下载以下几个文件 1)下载mtd-utils wget

http://debian.mirror.inra.fr/debian/pool/main/m/mtd-utils/mtd-utils_20080508.orig.tar.gz tar xzvf mtd-utils_20080508.orig.tar.gz cd mtd-utils-20080508

2)编译mtd-utils (主要是修改工具链) 修改Makefile文件: #CROSS=arm-linux-

修改为 CROSS=arm-marvell-linux-gnueabi- BUILDDIR := $(CROSS:-=) 修改为 BUILDDIR := .

修改ubi-utils/Makefile文件:

添加 CROSS=arm-marvell-linux-gnueabi- 修改 ubi-utils/new-utils/Makefile文件: 添加 CROSS=arm-marvell-linux-gnueabi-

make WITHOUT_XATTR=1

3) ubi-utils子目录下生成我们需要的ubiattach、ubimkvol等文件(请确保是交叉编译所得)

mkfs.ubifs子目录下生成我们需要的mkfs.ubifs工具,通过这个工具我们能打包一个文件夹,生成UBIFS系统镜像,

我是使用 nfs 启动, 直接解压文件到 flash 上,所以并没有使用 mkfs.ubifs工具.

另外网络上很多文中提到 zlib、lzo 这两个库,但是我并没有使用到。

如何使用UBIFS

1. 使用nfs启动系统, 首先建立设备节点: 以下操作可以用mdev –s 生成 mknod /dev/ubi_ctrl c 10 58 mknod /dev/ubi0 c 250 0

2、 执行以下命令挂载ubifs: 1.flash_eraseall /dev/mtd8 #擦出分区 2.ubiattach /dev/ubi_ctrl -m 8 –O #建立关联 3.ubimkvol /dev/ubi0 -N rootfs -s 30MiB ubimkvol创建容量, -s 是设置大小 , 此步的作用在于mtd8中没有烧录数据之前需要通过此步才可以挂载文件系统到挂载点下。由于此处用的是nfs和tar组合烧录,所以需要先挂载ubi设备文件到挂载点,才能进行解压,因此在挂载之前需要这一步。如果已经将镜像焼写到了相应块设备中,则可以免去这一句。

关于tar焼写文件的原理:

将任何一个文件夹下的目录进行tar打包之后,它们都是以二进制的文件存在,是脱离于文件系统的,将他们解压到某一个目录时,此目录的文件系统格式,就决定了它们在设备上的摆放方式,也就决定了它们在设备上所处的文件系统类型。如果tar了所有rootfs所具备的资源,并将他们tar vf –C 到ubi文件系统类型的目录下,那么它们无异与被写入了目录所挂载的相应的块设备,并以ubi文件系统的格式存在,那么和用nand write 或 flashcp 将用mkfs.ubifs

flashcp –v /opt/mtc/xxxx.ubifs /dev/mtd8

制作出来的的rootfs镜像没有区别,只是在生产时,有一定的限制,所以最好还是用nand write 提前焼写到nand flash在内核中对其的所分的相应分区地址空间内。如下:

Creating 6 MTD partitions on \

0x000000000000-0x000010000000 : \0x000000000000-0x000000800000 : \0x000000800000-0x000001000000 : \0x000001000000-0x000002000000 : \0x000002000000-0x000004000000 : \0x000004000000-0x000020000000 : \

4.mount -t ubifs ubi0_0 /mnt 或者mount -t ubifs ubi0:rootfs /mnt uboot 如何支持 UBIFS 为根文件系统启动

setenv bootargs console=ttyS0,115200 ubi.mtd=4 root=ubi0_0 rootfstype=ubifs

ip=192.168.1.101:192.168.1.100::255.255.255.0::usb0:on

下面附上一个我自己通过 nfs 启动以后, 烧写 kernel 和文件系统的脚本。 #!/bin/sh

TestResult() {

if [ $? -ne 0 ]; then

echo \ exit 1 else

echo \ echo \fi }

#Erase the flash partition

echo \Erase the flash partitin----------------\/mtd-utils/usr/sbin/flash_eraseall /dev/mtd3 /mtd-utils/usr/sbin/flash_eraseall /dev/mtd4 echo \Install kernel and software to flash----------------\

/bin/dd if=/zImage of=/dev/mtdblock3

mkdir -p /mountpoint

mknod /dev/ubi_ctrl c 10 58 mknod /dev/ubi0 c 250 0

/mtd-utils/ubi/ubiattach /dev/ubi_ctrl -m 8 –O 2048 TestResult \

/mtd-utils/ubi/ubimkvol /dev/ubi0 -N rootfs -s 30MiB

TestResult \/bin/mount -t ubifs ubi0_0 /mountpoint

TestResult \echo \tar xf /FSSoftware.tar -C /mountpoint sync

/bin/umount /mountpoint

echo

\echo \ Please set uboot environment: \

echo \rootfstype=ubifs

ip=192.168.1.101:192.168.1.100::255.255.255.0::usb0:on\echo

\exit 0 另外 ubifs 是一个异步的文件系统, 所以为了掉电的时候数据能保存完整, 最好使用 -o sync 挂载文件系统。

具体操作如下

U-Boot 1.3.1 (Sep 1 2012 - 00:07:37) - stm24_0057 DRAM: 256 MiB NOR: 4 MiB NAND: Bad block table found at page 262080, version 0x01 Bad block table found at page 262016, version 0x01 512 MiB In: serial Out: serial

usb usb1: Manufacturer: Linux 2.6.32.57_stm24_V5.0-EUD7141_7141-STSDK ehci_hcd usb usb1: SerialNumber: stm-ehci.0 usb usb1: configuration #1 chosen from 1 choice hub 1-0:1.0: USB hub found hub 1-0:1.0: 1 port detected stm-ehci stm-ehci.1: st-ehci stm-ehci stm-ehci.1: new USB bus registered, assigned bus number 2 stm-ehci stm-ehci.1: irq 160, io mem 0xfeaffe00 stm-ehci stm-ehci.1: USB 0.0 started, EHCI 1.00 usb usb2: New USB device found, idVendor=1d6b, idProduct=0002 usb usb2: New USB device strings: Mfr=3, Product=2, SerialNumber=1 usb usb2: Product: st-ehci usb usb2: Manufacturer: Linux 2.6.32.57_stm24_V5.0-EUD7141_7141-STSDK ehci_hcd usb usb2: SerialNumber: stm-ehci.1 usb usb2: configuration #1 chosen from 1 choice hub 2-0:1.0: USB hub found hub 2-0:1.0: 1 port detected Initializing USB Mass Storage driver... usbcore: registered new interface driver usb-storage USB Mass Storage support registered. mice: PS/2 mouse device common for all mice i2c /dev entries driver sh_tmu: TMU0 kept as earlytimer sh_tmu: TMU1 kept as earlytimer usbcore: registered new interface driver usbhid usbhid: v2.6:USB HID core driver [STM][PM-Sys]: emi @ 40 [STM][PM-Sys]: gpio @ 20 stm-hwrandom stm-hwrandom: STM Random Number Generator ver. 0.1 stm-rng hardware driver 1.0 configured nf_conntrack version 0.5.0 (1317 buckets, 5268 max) ip_tables: (C) 2000-2006 Netfilter Core Team ClusterIP Version 0.8 loaded successfully TCP cubic registered NET: Registered protocol family 10 IPv6 over IPv4 tunneling driver NET: Registered protocol family 17 drivers/rtc/hctosys.c: unable to open rtc device (rtc0) eth0: device MAC address 00:fa:e0:fa:e0:00 hub 1-0:1.0: over-current change on port 1 STMMAC MII Bus: probed No MAC Management Counters available IP-Config: Complete: device=eth0, addr=192.168.1.5, mask=255.255.255.0, gw=192.168.1.1, host=I01X088, domain=, nis-domain=(none), bootserver=255.255.255.255, rootserver=10.141.198.252, rootpath= Looking up port of RPC 100003/2 on 10.141.198.252 PHY: 1:01 - Link is Up - 100/Full Looking up port of RPC 100005/1 on 10.141.198.252 VFS: Mounted root (nfs filesystem) on device 0:12. Freeing unused kernel memory: 148k freed INIT: version 2.86 booting Fast Starting Kernel event manager... Activating swap. Checking all file systems... fsck from util-linux-ng 2.16.1 Mounting local filesystems... Cleaning /tmp /var/run /var/lock. Setting up networking...done. Hostname: I01X088.00. Configuring network interfaces: done. #!/bin/sh case \ start) /sbin/ubiattach /dev/ubi_ctrl -m 8 -O 2048 #/bin/mount -t ubifs /dev/ubi0 /opt/mtc /bin/mount -t ubifs ubi0_0 ~/mountpoint

#/bin/mount -t squashfs /dev/mtdblock7 /opt/mtc export MODULES_INSTALL_DIR=/opt/mtc/modules cd $MODULES_INSTALL_DIR; . load_modules.sh # point to new partitions export STMTD_BKUP_DEVICE=mtd5 export STMTD_MAIN_DEVICE=mtd6 #. /etc/stb.env if [ -e $MODULES_INSTALL_DIR/ecm_firmware.bin ] ; then echo \config.runtime [ -n \ fi cd ..; ./main*32BITS.out ;; :q! 用nand write写入之后进行关联ubifs

root@I01X088.00:~/mountpoint# /sbin/ubiattach /dev/ubi_ctrl -m 7 -O 2048 UBI: attaching mtd7 to ubi0 UBI: physical eraseblock size: 131072 bytes (128 KiB) UBI: logical eraseblock size: 126976 bytes UBI: smallest flash I/O unit: 2048 UBI: sub-page size: 512 UBI: VID header offset: 2048 (aligned 2048) UBI: data offset: 4096 UBI: empty MTD device detected UBI: create volume table (copy #1) UBI: create volume table (copy #2) UBI: attached mtd7 to ubi0 UBI: MTD device name: \UBI: MTD device size: 16 MiB UBI: number of good PEBs: 128 UBI: number of bad PEBs: 0 UBI: max. allowed volumes: 128 UBI: wear-leveling threshold: 4096 UBI: number of internal volumes: 1 UBI: number of user volumes: 0 UBI: available PEBs: 122 UBI: total number of reserved PEBs: 6 UBI: number of PEBs reserved for bad PEB handling: 2 UBI: max/mean erase counter: 0/0 UBI: image sequence number: 0 UBI: background thread \UBI device number 0, total 128 LEBs (16252928 bytes, 15.5 MiB), available 122 LEBs (15491072 bytes, 14.8 MiB), LEB size 126976 bytes (124.0 KiB) root@I01X088.00:~/mountpoint# /bin/mount -t ubifs ubi0_0 ~/mountpoint/ UBIFS error (pid 1223): ubifs_get_sb: cannot open \mount: unknown filesystem type 'ubifs'

root@I01X088.00:~/mountpoint# ubimkvol /dev/ubi0 -N rootfs -s 30MiB UBI error: ubi_create_volume: cannot create volume 0, error -28 ubimkvol: error!: cannot UBI create volume error 28 (No space left on device) 此处因为关联错分区,导致挂在失败

root@I01X088.00:~/mountpoint# ubi ubiattach ubiformat ubinize ubirsvol ubicrc32 ubimkvol ubirename ubiupdatevol ubidetach ubinfo ubirmvol root@I01X088.00:~/mountpoint# /sbin/ubidetach --help ubidetach version 1.5.0 - tool to remove UBI devices (detach MTD devices from UBI) Usage: ubidetach [] [-d ] [-m ] [-p ] [--devn=] [--mtdn=] [--dev-path=] UBI control device defaults to /dev/ubi_ctrl if not supplied. Example 1: ubidetach -p /dev/mtd0 - detach MTD device /dev/mtd0 Example 2: ubidetach -d 2 - delete UBI device 2 (ubi2) Example 3: ubidetach -m 0 - detach MTD device 0 (mtd0) -d, --devn= UBI device number to delete -p, --dev-path= or alternatively, MTD device node path to detach -m, --mtdn= or alternatively, MTD device number to detach -h, --help print help message -V, --version print program version root@I01X088.00:~/mountpoint# /sbin/ubidetach -p /dev/mtd7 用ubidetach命令删除已建关联。 UBI: mtd7 is detached from ubi0

root@I01X088.00:~/mountpoint# /sbin/ubidetach /dev/ubi_ctrl -m 8 -O 2048 重新建立关联 /sbin/ubidetach: invalid option -- 'O' Use -h for help root@I01X088.00:~/mountpoint# /sbin/ubiattach /dev/ubi_ctrl -m 8 -O 2048 UBI: attaching mtd8 to ubi0 UBI: physical eraseblock size: 131072 bytes (128 KiB) UBI: logical eraseblock size: 126976 bytes UBI: smallest flash I/O unit: 2048 UBI: sub-page size: 512 UBI: VID header offset: 2048 (aligned 2048) UBI: data offset: 4096 UBI warning: ubi_scan: 203 PEBs are corrupted corrupted PEBs are: 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 UBI: volume 0 (\UBI: attached mtd8 to ubi0 UBI: MTD device name: \UBI: MTD device size: 32 MiB UBI: number of good PEBs: 256 UBI: number of bad PEBs: 0 UBI: max. allowed volumes: 128 UBI: wear-leveling threshold: 4096 UBI: number of internal volumes: 1 UBI: number of user volumes: 1 UBI: available PEBs: 0 UBI: total number of reserved PEBs: 256 UBI: number of PEBs reserved for bad PEB handling: 2 UBI: max/mean erase counter: 1/0 UBI: image sequence number: 669128329 UBI: background thread \UBI device number 0, total 256 LEBs (32505856 bytes, 31.0 MiB), available 0 LEBs (0 bytes), LEB size 126976 bytes (124.0 KiB) root@I01X088.00:~/mountpoint# /bin/mount -t ubifs ubi0_0 ~/mountpoint/ 挂载已经焼写了rootfs,并被关联到ubi的分区 UBIFS: mounted UBI device 0, volume 0, name \UBIFS: file system size: 14983168 bytes (14632 KiB, 14 MiB, 118 LEBs) UBIFS: journal size: 2412544 bytes (2356 KiB, 2 MiB, 19 LEBs) UBIFS: media format: w4/r0 (latest is w4/r0) UBIFS: default compressor: lzo UBIFS: reserved for root: 0 bytes (0 KiB) root@I01X088.00:~/mountpoint# ls root@I01X088.00:~/mountpoint# cd .. root@I01X088.00:~# ls mountpoint mtraces.txt nfs printenv saveenv setenv root@I01X088.00:~# cd mountpoint/ root@I01X088.00:~/mountpoint# ls macros.ttm multicom-libstsdk macros_tests.ttm multicom_v4.0.5P2 main_eud7141_7141_ST40ESTB_LINUX_32BITS.out sdk-fonts modules stsdk-fonts modules_eud7141_7141_ST40ESTB_LINUX_32BITS 使用flashcp烧录后进行ubi关联

root@I01X088.00:~# flashcp -v ../mtc_jelly.ubifs /dev/mtd8 Erasing blocks: 53/53 (100%) Writing data: 6784k/0k (100%)) Verifying data: 6784k/0k (100%)) root@I01X088.00:~# ubiattach /dev/ubi_ctrl -m 8 -O 2048 UBI: attaching mtd8 to ubi0 UBI: physical eraseblock size: 131072 bytes (128 KiB)

UBI: logical eraseblock size: 126976 bytes UBI: smallest flash I/O unit: 2048 UBI: sub-page size: 512 UBI: VID header offset: 2048 (aligned 2048) UBI: data offset: 4096 UBI: volume 0 (\UBI: attached mtd8 to ubi0 UBI: MTD device name: \UBI: MTD device size: 32 MiB UBI: number of good PEBs: 256 UBI: number of bad PEBs: 0 UBI: max. allowed volumes: 128 UBI: wear-leveling threshold: 4096 UBI: number of internal volumes: 1 UBI: number of user volumes: 1 UBI: available PEBs: 0 UBI: total number of reserved PEBs: 256 UBI: number of PEBs reserved for bad PEB handling: 2 UBI: max/mean erase counter: 1/0 UBI: image sequence number: 669128329 UBI: background thread \UBI device number 0, total 256 LEBs (32505856 bytes, 31.0 MiB), available 0 LEBs (0 bytes), LEB size 126976 bytes (124.0 KiB) root@I01X088.00:~# mount -t ubifs ubi0_0 ~/mountpoint/ UBIFS: mounted UBI device 0, volume 0, name \UBIFS: file system size: 14983168 bytes (14632 KiB, 14 MiB, 118 LEBs) UBIFS: journal size: 2412544 bytes (2356 KiB, 2 MiB, 19 LEBs) UBIFS: media format: w4/r0 (latest is w4/r0) UBIFS: default compressor: lzo UBIFS: reserved for root: 0 bytes (0 KiB) root@I01X088.00:~# ls ls mountpoint mtraces.txt nfs printenv saveenv setenv root@I01X088.00:~# ls mountpoint mtraces.txt nfs printenv saveenv setenv root@I01X088.00:~# cd mountpoint/ root@I01X088.00:~/mountpoint# ls macros.ttm multicom-libstsdk macros_tests.ttm multicom_v4.0.5P2 main_eud7141_7141_ST40ESTB_LINUX_32BITS.out sdk-fonts modules stsdk-fonts modules_eud7141_7141_ST40ESTB_LINUX_32BITS root@I01X088.00:~/mountpoint# 通过nfs tar的方式进行ubi关联

I01X088.00 login: root

Linux I01X088.00 2.6.32.57_stm24_V5.0-EUD7141_7141-STSDK #4 PREEMPT Wed Sep 26 22:47:08 CST 2012 sh4 unknown unknown GNU/Linux Welcome to STMicroelectronics Base Distribution. Last login: Sat Jan 1 00:00:25 +0000 2000 on console. No mail. root@I01X088.00:~# flash_eraseall /dev/mtd8

flash_eraseall has been replaced by `flash_erase 0 0`; please use it Erasing 128 Kibyte @ 1fe0000 -- 100 % complete root@I01X088.00:~# ubiattach /dev/ubi_ctrl -m 8 -O 2048 UBI: attaching mtd8 to ubi0 UBI: physical eraseblock size: 131072 bytes (128 KiB) UBI: logical eraseblock size: 126976 bytes UBI: smallest flash I/O unit: 2048 UBI: sub-page size: 512 UBI: VID header offset: 2048 (aligned 2048) UBI: data offset: 4096 UBI: empty MTD device detected UBI: create volume table (copy #1) UBI: create volume table (copy #2) UBI: attached mtd8 to ubi0 UBI: MTD device name: \UBI: MTD device size: 32 MiB UBI: number of good PEBs: 256 UBI: number of bad PEBs: 0 UBI: max. allowed volumes: 128 UBI: wear-leveling threshold: 4096 UBI: number of internal volumes: 1 UBI: number of user volumes: 0 UBI: available PEBs: 250 UBI: total number of reserved PEBs: 6 UBI: number of PEBs reserved for bad PEB handling: 2 UBI: max/mean erase counter: 0/0 UBI: image sequence number: 0 UBI: background thread \UBI device number 0, total 256 LEBs (32505856 bytes, 31.0 MiB), available 250 LEBs (31744000 bytes, 30.3 MiB), LEB size 126976 bytes (124.0 KiB) root@I01X088.00:~# ubimkvol /dev/ubi0 -N rootfs -s 30MiB Volume ID 0, size 248 LEBs (31490048 bytes, 30.0 MiB), LEB size 126976 bytes (124.0 KiB), dynamic, name \root@I01X088.00:~# mount -t ubifs ubi0_0 ~/mountpoint/ UBIFS: default file-system created UBIFS: mounted UBI device 0, volume 0, name \UBIFS: file system size: 30347264 bytes (29636 KiB, 28 MiB, 239 LEBs) UBIFS: journal size: 1523712 bytes (1488 KiB, 1 MiB, 12 LEBs) UBIFS: media format: w4/r0 (latest is w4/r0) UBIFS: default compressor: lzo UBIFS: reserved for root: 1433376 bytes (1399 KiB) root@I01X088.00:~# tar -xvf /opt/mtc.tar –C ~/mountpoint/

本文来源:https://www.bwwdw.com/article/rq2r.html

Top