qtopia 文件系统启动过程分析

摘要:
Id=2300212虽然root_文件系统qtopia的GUI基于qtopia,但大多数初始化和启动都是由busybox完成的。Qtopia仅在启动的最后阶段启用。由于init=/linusrc在默认内核命令行上,所以在安装文件系统后运行的第一个程序是根目录中的linuxrc。事实上,root_qtopia中没有/etc/inittab配置文件。根据busybox的逻辑,它将生成默认配置副本代码staticvoidparse_inittab{#ifENABLE_FEATURE_USE_INITTABchar*token[4];parser_t*parser=config_open2;if#endif{/*Noinittabfile--setupsomedefaultbehavior*//*RebotonCtrlAlt-Del*/new_init_action;/*Umountallfilesystemsonhalt/reboot*/new_init _action;//*Swapoffonhalt/reoot*/ifnew_init_action;/*PreparestorestartinitwhenaQUITis received*/new_init_action;**Askfirstshellontty1-4*/new_init _action;//TODO:VC_1instead of“”?此宏的默认值为“/etc/init.d/rcS”。以下是/etc/init的内容。d/rcS,这也是我们要分析的关键拷贝代码#!

嵌入式学习入门http://blog.chinaunix.net/u3/117680/showart.php?id=2300212

虽然root_qtopia这个文件系统的GUI是基于Qtopia的,但其初始化启动过程却是由大部分由busybox完成,Qtopia(qpe)只是在启动的最后阶段被开启。
由于默认的内核命令行上有init=/linuxrc, 因此,在文件系统被挂载后,运行的第一个程序是根目录下的linuxrc。 这是一个指向/bin/busybox的链接,也就是说,系统起来后运行的第一个程序也就是busybox本身。
这种情况下,busybox首先将试图解析/etc/inittab来获取进一步的初始化配置信息(参考busybox源代码init/init.c中的 parse_inittab()函数)。而事实上,root_qtopia中并没有/etc/inittab这个配置文件,根据busybox的逻辑,它将生成默认的配置

复制代码

  1. static void parse_inittab(void)
  2. {
  3. #if ENABLE_FEATURE_USE_INITTAB
  4. char *token[4];
  5. parser_t *parser = config_open2("/etc/inittab", fopen_for_read);
  6. if (parser == NULL)
  7. #endif
  8. {
  9. /* No inittab file -- set up some default behavior */
  10. /* Reboot on Ctrl-Alt-Del */
  11. new_init_action(CTRLALTDEL, "reboot", "");
  12. /* Umount all filesystems on halt/reboot */
  13. new_init_action(SHUTDOWN, "umount -a -r", "");
  14. /* Swapoff on halt/reboot */
  15. if (ENABLE_SWAPONOFF)
  16. new_init_action(SHUTDOWN, "swapoff -a", "");
  17. /* Prepare to restart init when a QUIT is received */
  18. new_init_action(RESTART, "init", "");
  19. /* Askfirst shell on tty1-4 */
  20. new_init_action(ASKFIRST, bb_default_login_shell, "");
  21. //TODO: VC_1 instead of ""? "" is console -> ctty problems -> angry users
  22. new_init_action(ASKFIRST, bb_default_login_shell, VC_2);
  23. new_init_action(ASKFIRST, bb_default_login_shell, VC_3);
  24. new_init_action(ASKFIRST, bb_default_login_shell, VC_4);
  25. /* sysinit */
  26. new_init_action(SYSINIT, INIT_SCRIPT, "");
  27. return;
  28. }

其中, 最重要的一个,就是new_init_action(SYSINIT, INIT_SCRIPT, ""), 也就决定了接下去初始化的脚本是INIT_SCRIPT所定义的值。这个宏的默认值是"/etc/init.d/rcS".
下面是文件系统中/etc/init.d/rcS的内容, 也是我们要分析的重点

复制代码

  1. #! /bin/sh
  2. PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin:
  3. runlevel=S
  4. prevlevel=N
  5. umask 022
  6. export PATH runlevel prevlevel
  7. #
  8. # Trap CTRL-C &c only in this shell so we can interrupt subprocesses.
  9. #
  10. trap ":" INT QUIT TSTP
  11. /bin/hostname FriendlyARM
  12. /bin/mount -n -t proc none /proc
  13. /bin/mount -n -t sysfs none /sys
  14. /bin/mount -n -t usbfs none /proc/bus/usb
  15. /bin/mount -t ramfs none /dev
  16. echo /sbin/mdev > /proc/sys/kernel/hotplug
  17. /sbin/mdev -s
  18. /bin/hotplug
  19. # mounting file system specified in /etc/fstab
  20. mkdir -p /dev/pts
  21. mkdir -p /dev/shm
  22. /bin/mount -n -t devpts none /dev/pts -o mode=0622
  23. /bin/mount -n -t tmpfs tmpfs /dev/shm
  24. /bin/mount -n -t ramfs none /tmp
  25. /bin/mount -n -t ramfs none /var
  26. mkdir -p /var/empty
  27. mkdir -p /var/log
  28. mkdir -p /var/lock
  29. mkdir -p /var/run
  30. mkdir -p /var/tmp
  31. /sbin/hwclock -s
  32. syslogd
  33. /etc/rc.d/init.d/netd start
  34. echo " " > /dev/tty1
  35. echo "Starting networking..." > /dev/tty1
  36. sleep 1
  37. /etc/rc.d/init.d/httpd start
  38. echo " " > /dev/tty1
  39. echo "Starting web server..." > /dev/tty1
  40. sleep 1
  41. /etc/rc.d/init.d/leds start
  42. echo " " > /dev/tty1
  43. echo "Starting leds service..." > /dev/tty1
  44. echo " "
  45. sleep 1
  46. /sbin/ifconfig lo 127.0.0.1
  47. /etc/init.d/ifconfig-eth0
  48. /bin/qtopia &
  49. echo " " > /dev/tty1
  50. echo "Starting Qtopia, please waiting..." > /dev/tty1

下面就逐个来分析:

复制代码

  1. PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin:
  2. runlevel=S
  3. prevlevel=N
  4. umask 022
  5. export PATH runlevel prevlevel

为启动环境设置必要的环境变量;

复制代码

  1. /bin/hostname FriendlyARM

设置机器名字;

复制代码

  1. /bin/mount -n -t proc none /proc
  2. /bin/mount -n -t sysfs none /sys
  3. /bin/mount -n -t usbfs none /proc/bus/usb
  4. /bin/mount -t ramfs none /dev

挂载“虚拟”文件系统,/proc, /sys,并且在/dev目录上挂载一个ramfs,相当于把原本NAND Flash上的只读的/dev目录“覆盖”上一块可写的空的SDRAM。
这里要注意的是,/sys和挂载了ramfs的/dev是正确创建设备节点的关键。对于2.6.29内核来说,已经没有了devfs的支持,创建设备节点只有通过两种办法由文件系统完成:
1) 制作文件系统镜像前用mknod手动创建好系统中所有的(包括可能有的)设备节点,并把这些节点文件一起做进文件系统镜像中;
2)在文件系统初始化过程中,通过/sys目录所输出的信息,在/dev目录下动态的创建系统中当前实际有的设备节点。
显然,方法1)有很大的局限性,仅限于没有设备动态增加或减少的情况,不适用于很多设备热插拔的情况,比如U盘,SD卡等等。方法2)是目前大多数PC上 Linux的做法(基于udev实现)。这种方法有两个前提: /sys目录挂载和一个可写的/dev目录。这也就是为什么我们在这里需要挂载/sys和ramfs在/dev目录上。事实上,这种方法最早就是为热插拔设计的,你可以理解为当系统启动是,所有设备一下子全部“插入”了进来。qtopia 文件系统启动过程分析第1张
这里有一点要说明的是,在文件系统初始化跑到这里之前,原本的/dev目录下必须有一个的设备节点:/dev/console。
复制代码

  1. echo /sbin/mdev > /proc/sys/kernel/hotplug
  2. /sbin/mdev -s
  3. /bin/hotplug

这几个就是用来完成我上面所说的两个东西: 1)通过mdev -s 在/dev目录下建立必要的设备节点; 2)设置内核的hotplug handler为mdev, 即当设备热插拔时,由mdev接收来自内核的消息并作出相应的回应, 比如挂载U盘。
对于mdev,需要注意的是,文件系统里存在/etc/mdev.conf文件,它包含了mdev的配置信息。通过这个文件,我们可以自定义一些设备节点的名称或链接来满足特定的需要。这是root qtopia中mdev.conf的内容:

复制代码

  1. # system all-writable devices
  2. full        0:0    0666
  3. null        0:0    0666
  4. ptmx        0:0    0666
  5. random        0:0    0666
  6. tty        0:0    0666
  7. zero        0:0    0666
  8. # console devices
  9. tty[0-9]*    0:5    0660
  10. vc/[0-9]*    0:5    0660
  11. # serial port devices
  12. s3c2410_serial0    0:5    0666    =ttySAC0
  13. s3c2410_serial1    0:5    0666    =ttySAC1
  14. s3c2410_serial2    0:5    0666    =ttySAC2
  15. s3c2410_serial3    0:5    0666    =ttySAC3
  16. # loop devices
  17. loop[0-9]*    0:0    0660    =loop/
  18. # i2c devices
  19. i2c-0        0:0    0666    =i2c/0
  20. i2c-1        0:0    0666    =i2c/1
  21. # frame buffer devices
  22. fb[0-9]        0:0    0666
  23. # input devices
  24. mice        0:0    0660    =input/
  25. mouse.*        0:0    0660    =input/
  26. event.*        0:0    0660    =input/
  27. ts.*        0:0    0660    =input/
  28. # rtc devices
  29. rtc0        0:0    0644    >rtc
  30. rtc[1-9]    0:0    0644
  31. # misc devices
  32. mmcblk0p1    0:0    0600    =sdcard */bin/hotplug
  33. sda1        0:0    0600    =udisk * /bin/hotplug

可以看到,原本串口驱动注册的设备名是s3c2410_serial0, s3c2410_serial1和s3c2410_serial2,而mdev则会在/dev目录下对应生成ttySAC0, ttySAC1和ttySAC2以符合应用程序对于串口设备名称的习惯。同样的,/dev/sdcard和/dev/udisk永远分别指向SD卡和U盘的第一个分区。(所以,用那些没有分区表的SD卡或U盘的兄弟知道原因了吧...)

复制代码

  1. # mounting file system specified in /etc/fstab
  2. mkdir -p /dev/pts
  3. mkdir -p /dev/shm
  4. /bin/mount -n -t devpts none /dev/pts -o mode=0622
  5. /bin/mount -n -t tmpfs tmpfs /dev/shm
  6. /bin/mount -n -t ramfs none /tmp
  7. /bin/mount -n -t ramfs none /var
  8. mkdir -p /var/empty
  9. mkdir -p /var/log
  10. mkdir -p /var/lock
  11. mkdir -p /var/run
  12. mkdir -p /var/tmp

就像注释中所说的,这是用来挂载其他一些常用的文件系统,并在/var目录下(同样是ramfs,可写的)新建必要的目录。

复制代码

  1. /sbin/hwclock -s

用来设定系统时间的,从硬件RTC中获取,不过似乎有问题
接下来就是启动系统服务了,包括log记录,网络, http server和自定义的"跑马灯服务"...
关于mdev.conf中的

复制代码

  1. # misc devices
  2. mmcblk0p1    0:0    0600    =sdcard */bin/hotplug
  3. sda1        0:0    0600    =udisk * /bin/hotplug

一点补充说明:
这两句配置的意思是当SD卡或者U盘插入/拔出时,将这个消息传递给自定义的热插拔handler, /bin/hotplug. 这个程序是友善之臂开发的用于自动挂载可移动设备的,目前是SD卡和U盘。它的逻辑很简单,将SD卡或者U盘的第一个分区作为FAT/FAT32挂载到 /sdcard或者/udisk.
但这也同时带来一个问题,当SD卡或者U盘上没有分区表或者第一个分区不是FAT/FAT32格式的时候,它就玩不转了,兄弟们要小心了:)
这是/bin/hotplug里的二进制数据片段,可以看到我上面说的逻辑:
000010d0h: 52 00 00 00 4D 00 00 00 00 00 00 00 41 00 00 00 ; R...M.......A...
000010e0h: 43 00 00 00 54 00 00 00 49 00 00 00 4F 00 00 00 ; C...T...I...O...
000010f0h: 4E 00 00 00 00 00 00 00 44 00 00 00 45 00 00 00 ; N.......D...E...
00001100h: 56 00 00 00 4E 00 00 00 41 00 00 00 4D 00 00 00 ; V...N...A...M...
00001110h: 45 00 00 00 00 00 00 00 61 00 00 00 64 00 00 00 ; E.......a...d...
00001120h: 64 00 00 00 00 00 00 00 72 00 00 00 65 00 00 00 ; d.......r...e...
00001130h: 6D 00 00 00 6F 00 00 00 76 00 00 00 65 00 00 00 ; m...o...v...e...
00001140h: 00 00 00 00 2F 00 00 00 64 00 00 00 65 00 00 00 ; ..../...d...e...
00001150h: 76 00 00 00 2F 00 00 00 75 00 00 00 64 00 00 00 ; v.../...u...d...
00001160h: 69 00 00 00 73 00 00 00 6B 00 00 00 00 00 00 00 ; i...s...k.......
00001170h: 2F 00 00 00 64 00 00 00 65 00 00 00 76 00 00 00 ; /...d...e...v...
00001180h: 2F 00 00 00 73 00 00 00 64 00 00 00 63 00 00 00 ; /...s...d...c...
00001190h: 61 00 00 00 72 00 00 00 64 00 00 00 00 00 00 00 ; a...r...d.......
000011a0h: 4D 00 00 00 44 00 00 00 45 00 00 00 56 00 00 00 ; M...D...E...V...
000011b0h: 00 00 00 00 6D 00 00 00 6D 00 00 00 63 00 00 00 ; ....m...m...c...
000011c0h: 62 00 00 00 6C 00 00 00 6B 00 00 00 30 00 00 00 ; b...l...k...0...
000011d0h: 70 00 00 00 31 00 00 00 00 00 00 00 73 00 00 00 ; p...1.......s...
000011e0h: 64 00 00 00 61 00 00 00 31 00 00 00 00 00 00 00 ; d...a...1.......
000011f0h: 76 00 00 00 66 00 00 00 61 00 00 00 74 00 00 00 ; v...f...a...t...
00001200h: 00 00 00 00 2F 00 00 00 64 00 00 00 65 00 00 00 ; ..../...d...e...
00001210h: 76 00 00 00 2F 00 00 00 77 00 00 00 61 00 00 00 ; v.../...w...a...
00001220h: 74 00 00 00 63 00 00 00 68 00 00 00 64 00 00 00 ; t...c...h...d...
00001230h: 6F 00 00 00 67 00 00 00 00 00 00 00 9A B2 01 81 ; o...g.......毑.?
00001240h: B0                                              ; ?
复制代码

  1. syslogd
  2. /etc/rc.d/init.d/netd start
  3. echo "                        " > /dev/tty1
  4. echo "Starting networking..." > /dev/tty1
  5. sleep 1
  6. /etc/rc.d/init.d/httpd start
  7. echo "                        " > /dev/tty1
  8. echo "Starting web server..." > /dev/tty1
  9. sleep 1
  10. /etc/rc.d/init.d/leds start
  11. echo "                        " > /dev/tty1
  12. echo "Starting leds service..." > /dev/tty1
  13. echo "                        "
  14. sleep 1

启动一系列服务:
syslog - 用于记录内核和应用程序debug信息
netd -     inetd, 一个挂载启动各种网络相关服务的看守进程
httpd -    http server看守进程
leds  -   跑马灯看守进程
其中,inetd的配置文件为/etc/inetd.conf,这是文件内容

复制代码

  1. # /etc/inetd.conf:  see inetd(8) for further informations.
  2. echo     stream  tcp    nowait    root    internal
  3. echo     dgram   udp    wait    root    internal
  4. daytime  stream  tcp    nowait    root    internal
  5. daytime  dgram   udp    wait    root    internal
  6. time     stream  tcp    nowait    root    internal
  7. time     dgram   udp    wait    root    internal
  8. # These are standard services.
  9. #
  10. ftp    stream    tcp    nowait    root    /usr/sbin/ftpd        /usr/sbin/ftpd
  11. telnet    stream    tcp    nowait    root    /usr/sbin/telnetd    /usr/sbin/telnetd -i

可以看到,这里启动的网络服务有两个: 1)ftp server 和 2)telnet server。有关网络服务的端口和协议等具体信息,可以参考/etc/services, /etc/protocols
再接下来

复制代码

  1. /sbin/ifconfig lo 127.0.0.1
  2. /etc/init.d/ifconfig-eth0

配置网络设备(网卡):
1)设定本机回环地址为127.0.0.1
2)运行网卡设置脚本/etc/init.d/ifconfig-eth0
这是/etc/init.d/ifconfig-eth0的内容, 加入了我的一些注释

复制代码

  1. #!/bin/sh
  2. echo -n Try to bring eth0 interface up......>/dev/ttySAC0
  3. #判断/etc/eth0-setting文件是否存在
  4. if [ -f /etc/eth0-setting ] ; then
  5.                      #读取配置文件信息
  6.     source /etc/eth0-setting
  7.                       #如果根文件系统为nfs,则说明网卡已经配置OK,这里什么都不需要配置了
  8.     if grep -q "^/dev/root / nfs " /etc/mtab ; then
  9.         echo -n NFS root ... > /dev/ttySAC0
  10.                      #否则,根据配置文件中的MAC, IP, Mask和Gateway通过ifconfig命令相应地配置网卡
  11.     else
  12.         ifconfig eth0 down
  13.         ifconfig eth0 hw ether $MAC
  14.         ifconfig eth0 $IP netmask $Mask up
  15.         route add default gw $Gateway
  16.     fi
  17.                      #将配置文件中的DNS设置写入/etc/resolv.conf使之生效
  18.     echo nameserver $DNS > /etc/resolv.conf
  19. #配置文件不存在,使用默认配置
  20. else
  21.                       #如果根文件系统为nfs,则说明网卡已经配置OK,这里什么都不需要配置了
  22.     if grep -q "^/dev/root / nfs " /etc/mtab ; then
  23.         echo -n NFS root ... > /dev/ttySAC0
  24.     else
  25.                      #将网卡的IP地址设定为192.168.1.230
  26.     /sbin/ifconfig eth0 192.168.1.230 netmask 255.255.255.0 up
  27.     fi
  28. fi
  29. echo Done > /dev/ttySAC0

可以看到,NFS自动识别就是靠判断/etc/mtab中是否有nfs的挂载记录实现的。
这是root qtopia文件系统中/etc/eth0-settings文件

复制代码

  1. IP=192.168.1.230
  2. Mask=255.255.255.0
  3. Gateway=192.168.1.1
  4. DNS=192.168.1.1
  5. MAC=08:90:90:90:90:90

终于到最后了,启动Qtopia GUI环境

复制代码

  1. /bin/qtopia &
  2. echo "                                  " > /dev/tty1
  3. echo "Starting Qtopia, please waiting..." > /dev/tty1

可以看到,这里Qtopia是通过运行/bin/qtopia来启动的。事实上,/bin/qtopia也是一个脚本,它的任务是设定Qtopia运行必要的环境, 最后通过调用qpe可执行文件真正启动Qtopia。这是它的全部内容,我加入了一些注释:

复制代码

  1. #!/bin/sh
  2. #tslib环境变量设置,包括了touchscreen设备文件,tslib配置文件,tslib plug-in位置和touchscreen校准数据文件
  3. export TSLIB_TSDEVICE=/dev/input/event0
  4. export TSLIB_CONFFILE=/usr/local/etc/ts.conf
  5. export TSLIB_PLUGINDIR=/usr/local/lib/ts
  6. export TSLIB_CALIBFILE=/etc/pointercal
  7. #Qtopia环境变量设置,设定了Qtopia主要文件位置
  8. export QTDIR=/opt/Qtopia
  9. export QPEDIR=/opt/Qtopia
  10. #设定PATH和LD_LIBRARY_PATH以包含Qtopia的可执行文件和共享库文件,方便Qtopia正确运行
  11. export PATH=$QTDIR/bin:$PATH
  12. export LD_LIBRARY_PATH=$QTDIR/lib:/usr/local/lib:$LD_LIBRARY_PATH
  13. #通过判断/sys/devices/virtual/input/input0/uevent中是否包含touchscreen信息使Qtopia自动识别touchscreen和USB鼠标
  14. TS_INFO_FILE=/sys/devices/virtual/input/input0/uevent
  15. if [ -e $TS_INFO_FILE -a "/bin/grep -q TouchScreen < $TS_INFO_FILE" ]; then
  16.     export QWS_MOUSE_PROTO="TPanel:/dev/input/event0 USB:/dev/input/mice"
  17.     if [ -e /etc/pointercal -a ! -s /etc/pointercal ] ; then
  18.         rm /etc/pointercal
  19.     fi
  20. else
  21.     export QWS_MOUSE_PROTO="USB:/dev/input/mice"
  22.     >/etc/pointercal
  23. fi
  24. unset TS_INFO_FILE
  25. export QWS_KEYBOARD=TTY:/dev/tty1
  26. export KDEDIR=/opt/kde
  27. export HOME=/root
  28. #通过调用/opt/Qtopia/bin/qpe真正启动Qtopia
  29. exec $QPEDIR/bin/qpe 1>/dev/null 2>/dev/null

到此为止,文件系统从初始化到最终启动Qtopia GUI环境的全部过程就结束了,大家可以看到,友善之臂的“小秘密”其实都在这里,说穿了很简单:)只要大家能够静下心来认真看看脚本,看看源代码,加上一些背景知识的了解,搞清楚一个嵌入式系统就这么简单qtopia 文件系统启动过程分析第1张
/////////////////////////////////////////
通常/linuxrc这个文件只有在
1. 使用了Initial Ramdisk (initrd)
2. 内核命令行上指定了init=/linuxrc
这两种情况下才有用,mini2440的root_qtopia属于情况2), 在root_qtopia中,/linuxrc是指向/bin/busybox的符号链接,也就是说,整个文件系统的入口就变成了busybox的 main()函数,busybox支持这种方式来启动busybox本身和整个文件系统的初始化。

嵌入式学习入门http://blog.chinaunix.net/u3/117680/showart.php?id=2300212

免责声明:文章转载自《qtopia 文件系统启动过程分析》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇让 idea webstorm phpstorm 能够 识别 thinkphp 的方法(自动提示功能)设计模式之外观模式(门面模式)以及如何利用到接口设计中下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

HDFS+MapReduce+Hive+HBase十分钟快速入门

  1.     前言 本文的目的是让一个从未接触Hadoop的人,在很短的时间内快速上手,掌握编译、安装和简单的使用。 2.     Hadoop家族 截止2009-8-19日,整个Hadoop家族由以下几个子项目组成: 成员名 用途 Hadoop Common Hadoop体系最底层的一个模块,为Hadoop各子项目提供各种工具,如:配置文件和...

input标签与label标签的“合作关系”

一直忽略了input和label的关系。一次在做自定义单选框的时候又重新捡起来这对“兄弟”。 label的for属性和input的id值一致的话,input和label就会组成一个组。例如: <label for="test"> <input type="checkbox" id="test" abc="1111" /> &...

python文件路径分隔符的详细分析

写了挺久的python,文件分隔符的掌握肯定是必须的,但是我之前写的都是不规范的文件路径分隔符,例如‘’C:User emppython.txt’,一直都没有报过错。也不知为啥,今天查阅资料才知道自己写的都是些假的python,所以就在此记录一下。 主要是需要考虑分隔符的问题:在Windows系统下的分隔符是: (反斜杠)。 在Linux系统下的分隔符是:...

thinkphp的目录结构设计经验总结1

---恢复内容开始--- 用thinkphp开发了好些项目了;最近准备抽空写一些经验总结; 希望能给刚开始接触tp的童鞋们提供一些开发的方案;少走一些弯路;少踩一些坑; 这些绝对都是些精华干货;耐着性子阅读;相信肯定是会有收获的; 可以结合git项目对照研究:http://git.oschina.net/shuaibai123/thinkphp-bjyad...

97 条 Linux 常用命令及Vim命令总结

一:Vim编辑模式命令 基本上Vim共分为3种模式,分别是一般模式,编辑模式和命令行模式,这三种模式的作用分别如下简述: 一般模式:默认模式。打开vim直接进入的是一般模式,在这个模式下,可以进行的操作有:移动光标,复制,粘贴,删除。 编辑模式:编辑文件内容,在界面左下方会出现INSERT的字样。 命令行模式:查找、读取、保存、替换字符、显示行号、离开v...

JQuery选择器大全

jQuery 的选择器可谓之强大无比,这里简单地总结一下常用的元素查找方法 $("#myELement") 选择id值等于myElement的元素,id值不能重复在文档中只能有一个id值是myElement所以得到的是唯一的元素 $("div") 选择所有的div标签元素,返回div元素数组 $(".myClass") 选择使用myClass类的css的所有...