问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

如何安装ipk包

发布网友 发布时间:2022-04-26 00:37

我来回答

2个回答

热心网友 时间:2023-10-25 10:15

  ipk文件实际上是用ar命令打包的一个归档包。没有数字签名的ipk中一般包含control.tar.gz、data.tar.gz和debian-binary这三个文件。

  其中debian-binary里面是固定的。

  control.tar.gz中包含了control、md5sums、preinst、postinst、prerm、postrm这几个文件,其中control是必须的,其它都是可选的。

  data.tar.gz中包含了要安装的程序和数据。

  ipk的安装对于大多数用户来说都是使用preware、WebOS Quick Install、Internalz Pro来安装程序的。如果不考虑postinst脚本,那么使用这些工具安装的文件都是相对于/media/cryptofs/apps目录进行安装的。如果直接使用不带-o参数的ipkg install命令安装的话,那么安装的文件都是相对于/目录的。也就是说ipk包中实际上并不包含相对于那个路径进行安装的信息。安装到哪儿只跟安装的方式有关。

  rootfs.tar.gz中那些预先安装好的包都是相对于/目录安装的。相对于/目录安装的程序,用户通过preware、WebOS Quick Install和系统自带的软件包管理器都是无法卸载的,但并不是说就真的无法卸载,实际上只要你愿意,这些包都可以在root帐号下用ipkg remove命令来卸载掉。

  我们在上一节中有一个<carrier>.tar没有介绍(<carrier>表示att、wr、verizon等),之所以没介绍主要原因就是我们需要先了解上面的这些内容,然后才比较容易解释这个<carrier>.tar。

  这个<carrier>.tar中的主要内容就是一些ipk包,另外,还有一个installer.xml。这个installer.xml如果不是要做跨运营商或跨机型移植,是不需要修改的。那么剩下的就是运营商定制的一些ipk包了。这些包是在刷机程序把rootfs.tar.gz写入设备之后,进行安装的。他们都是相对于/目录进行安装的。因此这些包从本质上来讲,跟rootfs.tar.gz中预先安装的包是没有区别的。唯一的区别就是rootfs.tar.gz中的包是预先安装好的,<carrier>.tar中的包是在刷机过程中进行安装的。而ROM验证md5sums的过程是在<carrier>.tar中的所有ipk安装之后才进行的。因此,<carrier>.tar中的包也是需要进行md5sums验证的。

  既然<carrier>.tar中的包也需要验证,所以对于放在<carrier>.tar中的包来说,它的control.tar.gz中的md5sums不是可选的,而是必须的。如果缺少了这个md5sums,那么刷机到82%时,同样会因为无法通过md5sums验证而终止刷机,无法重启。

  要生成一个带md5sums的ipk,如果靠手工来计算编写md5sums,并自己通过tar、gzip、ar等命令来打包实在是麻烦的很。实际上前人早在10年前就做好了这样的打包脚本,叫ipkg-build。我们可以直接拿来用。

  下面是这个脚本的完整内容:

  #!/bin/sh
  
  # ipkg-build -- construct a .ipk from a directory
  # Carl Worth <cworth@east.isi.e>
  # based on a script by Steve Redler IV, steve@sr-tech.com 5-21-2001
  set -e
  
  ipkg_extract_value() {
  sed -e "s/^[^:]*:[[:space:]]*//"
  }
  
  required_field() {
  field=$1
  
  value=`grep "^$field:" < $CONTROL/control | ipkg_extract_value`
  if [ -z "$value" ]; then
  echo "*** Error: $CONTROL/control is missing field $field" >&2
  return 1
  fi
  echo $value
  return 0
  }
  
  pkg_appears_sane() {
  local pkg_dir=$1
  
  local owd=`pwd`
  cd $pkg_dir
  
  PKG_ERROR=0
  
  large_uid_files=`find . -uid +99`
  if [ -n "$large_uid_files" ]; then
  echo "*** Warning: The following files have a UID greater than 99.
  You probably want to chown these to a system user: " >&2
  ls -ld $large_uid_files
  echo >&2
  fi
  
  
  if [ ! -f "$CONTROL/control" ]; then
  echo "*** Error: Control file $pkg_dir/$CONTROL/control not found." >&2
  cd $owd
  return 1
  fi
  
  pkg=`required_field Package`
  [ "$?" -ne 0 ] && PKG_ERROR=1
  
  version=`required_field Version | sed 's/.*://;'`
  [ "$?" -ne 0 ] && PKG_ERROR=1
  
  arch=`required_field Architecture`
  [ "$?" -ne 0 ] && PKG_ERROR=1
  
  required_field Maintainer >/dev/null
  [ "$?" -ne 0 ] && PKG_ERROR=1
  
  required_field Description >/dev/null
  [ "$?" -ne 0 ] && PKG_ERROR=1
  
  section=`required_field Section`
  [ "$?" -ne 0 ] && PKG_ERROR=1
  if [ -z "$section" ]; then
  echo "The Section field should have one of the following values:" >&2
  echo "Games, Multimedia, Communications, Settings, Utilies, Applications, Console, Misc" >&2
  fi
  
  priority=`required_field Priority`
  [ "$?" -ne 0 ] && PKG_ERROR=1
  if [ -z "$priority" ]; then
  echo "The Priority field should have one of the following values:" >&2
  echo "required, important, standard, optional, extra." >&2
  echo "If you don't know which priority value you should be using, then use \`optional'" >&2
  fi
  
  if echo $pkg | grep '[^a-z0-9.+-]'; then
  echo "*** Error: Package name $name contains illegal characters, (other than [a-z0-9.+-])" >&2
  PKG_ERROR=1;
  fi
  
  local bad_fields=`sed -ne 's/^\([^[:space:]][^:[:space:]]\+[[:space:]]\+\)[^:].*/\1/p' < $CONTROL/control | sed -e 's/\\n//'`
  if [ -n "$bad_fields" ]; then
  bad_fields=`echo $bad_fields`
  echo "*** Error: The following fields in $CONTROL/control are missing a ':'" >&2
  echo " $bad_fields" >&2
  echo "ipkg-build: This may be e to a missing initial space for a multi-line field value" >&2
  PKG_ERROR=1
  fi
  
  for script in $CONTROL/preinst $CONTROL/postinst $CONTROL/prerm $CONTROL/postrm; do
  if [ -f $script -a ! -x $script ]; then
  echo "*** Error: package script $script is not executable" >&2
  PKG_ERROR=1
  fi
  done
  
  if [ -f $CONTROL/conffiles ]; then
  for cf in `cat $CONTROL/conffiles`; do
  if [ ! -f ./$cf ]; then
  echo "*** Error: $CONTROL/conffiles mentions conffile $cf which does not exist" >&2
  PKG_ERROR=1
  fi
  done
  fi
  
  cd $owd
  return $PKG_ERROR
  }
  
  ###
  # ipkg-build "main"
  ###
  
  case $# in
  1)
  dest_dir=.
  ;;
  2)
  dest_dir=$2
  ;;
  *)
  echo "Usage: ipkg-build <pkg_directory> [<destination_directory>]" >&2
  exit 1
  ;;
  esac
  
  pkg_dir=$1
  
  if [ ! -d $pkg_dir ]; then
  echo "*** Error: Directory $pkg_dir does not exist" >&2
  exit 1
  fi
  
  # CONTROL is second so that it takes precedence
  CONTROL=
  [ -d $pkg_dir/DEBIAN ] && CONTROL=DEBIAN
  [ -d $pkg_dir/CONTROL ] && CONTROL=CONTROL
  if [ -z "$CONTROL" ]; then
  echo "*** Error: Directory $pkg_dir has no CONTROL subdirectory." >&2
  exit 1
  fi
  
  if ! pkg_appears_sane $pkg_dir; then
  echo >&2
  echo "ipkg-build: Please fix the above errors and try again." >&2
  exit 1
  fi
  
  tmp_dir=$dest_dir/IPKG_BUILD.$$
  mkdir $tmp_dir
  
  (cd $pkg_dir/data; find . -type f -print0 | xargs -0 md5sum ) > $pkg_dir/$CONTROL/md5sums
  if [ ! -f "$pkg_dir/files.txt" ]; then
  (cd $pkg_dir/data; find . -type f -print0 |xargs -0 grep '' -l) >$pkg_dir/files.txt
  fi
  # tar -C $pkg_dir/data -cf $tmp_dir/data.tar -T $pkg_dir/files.txt -h --verify
  tar -C $pkg_dir/data -cf $tmp_dir/data.tar . --verify
  gzip -f $tmp_dir/data.tar
  tar -C $pkg_dir/$CONTROL -czf $tmp_dir/control.tar.gz .
  
  echo "2.0" > $tmp_dir/debian-binary
  
  pkg_file=$dest_dir/${pkg}_${version}_${arch}.ipk
  #tar -C $tmp_dir -czf $pkg_file ./debian-binary ./data.tar.gz ./control.tar.gz
  (cd $tmp_dir ;ar -qc $pkg_file ./debian-binary ./data.tar.gz ./control.tar.gz ; mv $pkg_file ../)
  rm $tmp_dir/debian-binary $tmp_dir/data.tar.gz $tmp_dir/control.tar.gz
  rmdir $tmp_dir
  
  echo "Packaged contents of $pkg_dir into $pkg_file"
  这个脚本我对它作过一处非常细微的修改,旧的脚本中在打包data.tar.gz时,对软连接和硬连接是将连接指向的文件进行打包的。而实际上我们没有必要这样做,我们可以直接将连接以原始方式打包到ipk的data.tar.gz中,这是ipk包允许的。而且实际上webOS系统中原本有好多包本来就是带有软连接的,如果不做这个修改,后面我们就不能正确的将系统全部打包回ipk。

  好了,有了这个脚本,我们就可以自制ipk包了。首先建立一个包的目录,通常我们以包名来命名,然后在其下建立两个目录,分别为CONTROL和data,注意大小写。

  CONTROL目录下放control.tar.gz解压之后的内容。其中不必包含md5sums,即使包含在打包时也会重新生成,因此不必担心md5sums的正确性。

  data目录下放data.tar.gz解压之后的内容。注意它是相对于/的,里面的内容要包含相对于/的路径。另外,即使你希望这些内容被安装到/media/cryptofs/apps,也不要把这个路径建立到data目录下,这个路径是在安装时才决定的。

  之后你可以对这两个目录下的内容进行修改编辑,添加删除内容都可以。修改完毕之后,退回到这个包目录的上级目录下,然后将其拥有者和用户组都改为root(对于普通包是这样的,对于系统包来说,我们应该在解压系统包时就保留系统包的用户组,在修改时不要变更原来文件的用户组)。最后执行ipkg-build 包名,就可以重新打包生成修改之后的ipk了。

热心网友 时间:2023-10-25 10:15

ipk的安装对于大多数用户来说都是使用preware、WebOS Quick Install、Internalz Pro来安装程序的。如果不考虑postinst脚本,那么使用这些工具安装的文件都是相对于/media/cryptofs/apps目录进行安装的。如果直接使用不带-o参数的ipkg install命令安装的话,那么安装的文件都是相对于/目录的。也就是说ipk包中实际上并不包含相对于那个路径进行安装的信息。安装到哪儿只跟安装的方式有关。

热心网友 时间:2023-10-25 10:15

  ipk文件实际上是用ar命令打包的一个归档包。没有数字签名的ipk中一般包含control.tar.gz、data.tar.gz和debian-binary这三个文件。

  其中debian-binary里面是固定的。

  control.tar.gz中包含了control、md5sums、preinst、postinst、prerm、postrm这几个文件,其中control是必须的,其它都是可选的。

  data.tar.gz中包含了要安装的程序和数据。

  ipk的安装对于大多数用户来说都是使用preware、WebOS Quick Install、Internalz Pro来安装程序的。如果不考虑postinst脚本,那么使用这些工具安装的文件都是相对于/media/cryptofs/apps目录进行安装的。如果直接使用不带-o参数的ipkg install命令安装的话,那么安装的文件都是相对于/目录的。也就是说ipk包中实际上并不包含相对于那个路径进行安装的信息。安装到哪儿只跟安装的方式有关。

  rootfs.tar.gz中那些预先安装好的包都是相对于/目录安装的。相对于/目录安装的程序,用户通过preware、WebOS Quick Install和系统自带的软件包管理器都是无法卸载的,但并不是说就真的无法卸载,实际上只要你愿意,这些包都可以在root帐号下用ipkg remove命令来卸载掉。

  我们在上一节中有一个<carrier>.tar没有介绍(<carrier>表示att、wr、verizon等),之所以没介绍主要原因就是我们需要先了解上面的这些内容,然后才比较容易解释这个<carrier>.tar。

  这个<carrier>.tar中的主要内容就是一些ipk包,另外,还有一个installer.xml。这个installer.xml如果不是要做跨运营商或跨机型移植,是不需要修改的。那么剩下的就是运营商定制的一些ipk包了。这些包是在刷机程序把rootfs.tar.gz写入设备之后,进行安装的。他们都是相对于/目录进行安装的。因此这些包从本质上来讲,跟rootfs.tar.gz中预先安装的包是没有区别的。唯一的区别就是rootfs.tar.gz中的包是预先安装好的,<carrier>.tar中的包是在刷机过程中进行安装的。而ROM验证md5sums的过程是在<carrier>.tar中的所有ipk安装之后才进行的。因此,<carrier>.tar中的包也是需要进行md5sums验证的。

  既然<carrier>.tar中的包也需要验证,所以对于放在<carrier>.tar中的包来说,它的control.tar.gz中的md5sums不是可选的,而是必须的。如果缺少了这个md5sums,那么刷机到82%时,同样会因为无法通过md5sums验证而终止刷机,无法重启。

  要生成一个带md5sums的ipk,如果靠手工来计算编写md5sums,并自己通过tar、gzip、ar等命令来打包实在是麻烦的很。实际上前人早在10年前就做好了这样的打包脚本,叫ipkg-build。我们可以直接拿来用。

  下面是这个脚本的完整内容:

  #!/bin/sh
  
  # ipkg-build -- construct a .ipk from a directory
  # Carl Worth <cworth@east.isi.e>
  # based on a script by Steve Redler IV, steve@sr-tech.com 5-21-2001
  set -e
  
  ipkg_extract_value() {
  sed -e "s/^[^:]*:[[:space:]]*//"
  }
  
  required_field() {
  field=$1
  
  value=`grep "^$field:" < $CONTROL/control | ipkg_extract_value`
  if [ -z "$value" ]; then
  echo "*** Error: $CONTROL/control is missing field $field" >&2
  return 1
  fi
  echo $value
  return 0
  }
  
  pkg_appears_sane() {
  local pkg_dir=$1
  
  local owd=`pwd`
  cd $pkg_dir
  
  PKG_ERROR=0
  
  large_uid_files=`find . -uid +99`
  if [ -n "$large_uid_files" ]; then
  echo "*** Warning: The following files have a UID greater than 99.
  You probably want to chown these to a system user: " >&2
  ls -ld $large_uid_files
  echo >&2
  fi
  
  
  if [ ! -f "$CONTROL/control" ]; then
  echo "*** Error: Control file $pkg_dir/$CONTROL/control not found." >&2
  cd $owd
  return 1
  fi
  
  pkg=`required_field Package`
  [ "$?" -ne 0 ] && PKG_ERROR=1
  
  version=`required_field Version | sed 's/.*://;'`
  [ "$?" -ne 0 ] && PKG_ERROR=1
  
  arch=`required_field Architecture`
  [ "$?" -ne 0 ] && PKG_ERROR=1
  
  required_field Maintainer >/dev/null
  [ "$?" -ne 0 ] && PKG_ERROR=1
  
  required_field Description >/dev/null
  [ "$?" -ne 0 ] && PKG_ERROR=1
  
  section=`required_field Section`
  [ "$?" -ne 0 ] && PKG_ERROR=1
  if [ -z "$section" ]; then
  echo "The Section field should have one of the following values:" >&2
  echo "Games, Multimedia, Communications, Settings, Utilies, Applications, Console, Misc" >&2
  fi
  
  priority=`required_field Priority`
  [ "$?" -ne 0 ] && PKG_ERROR=1
  if [ -z "$priority" ]; then
  echo "The Priority field should have one of the following values:" >&2
  echo "required, important, standard, optional, extra." >&2
  echo "If you don't know which priority value you should be using, then use \`optional'" >&2
  fi
  
  if echo $pkg | grep '[^a-z0-9.+-]'; then
  echo "*** Error: Package name $name contains illegal characters, (other than [a-z0-9.+-])" >&2
  PKG_ERROR=1;
  fi
  
  local bad_fields=`sed -ne 's/^\([^[:space:]][^:[:space:]]\+[[:space:]]\+\)[^:].*/\1/p' < $CONTROL/control | sed -e 's/\\n//'`
  if [ -n "$bad_fields" ]; then
  bad_fields=`echo $bad_fields`
  echo "*** Error: The following fields in $CONTROL/control are missing a ':'" >&2
  echo " $bad_fields" >&2
  echo "ipkg-build: This may be e to a missing initial space for a multi-line field value" >&2
  PKG_ERROR=1
  fi
  
  for script in $CONTROL/preinst $CONTROL/postinst $CONTROL/prerm $CONTROL/postrm; do
  if [ -f $script -a ! -x $script ]; then
  echo "*** Error: package script $script is not executable" >&2
  PKG_ERROR=1
  fi
  done
  
  if [ -f $CONTROL/conffiles ]; then
  for cf in `cat $CONTROL/conffiles`; do
  if [ ! -f ./$cf ]; then
  echo "*** Error: $CONTROL/conffiles mentions conffile $cf which does not exist" >&2
  PKG_ERROR=1
  fi
  done
  fi
  
  cd $owd
  return $PKG_ERROR
  }
  
  ###
  # ipkg-build "main"
  ###
  
  case $# in
  1)
  dest_dir=.
  ;;
  2)
  dest_dir=$2
  ;;
  *)
  echo "Usage: ipkg-build <pkg_directory> [<destination_directory>]" >&2
  exit 1
  ;;
  esac
  
  pkg_dir=$1
  
  if [ ! -d $pkg_dir ]; then
  echo "*** Error: Directory $pkg_dir does not exist" >&2
  exit 1
  fi
  
  # CONTROL is second so that it takes precedence
  CONTROL=
  [ -d $pkg_dir/DEBIAN ] && CONTROL=DEBIAN
  [ -d $pkg_dir/CONTROL ] && CONTROL=CONTROL
  if [ -z "$CONTROL" ]; then
  echo "*** Error: Directory $pkg_dir has no CONTROL subdirectory." >&2
  exit 1
  fi
  
  if ! pkg_appears_sane $pkg_dir; then
  echo >&2
  echo "ipkg-build: Please fix the above errors and try again." >&2
  exit 1
  fi
  
  tmp_dir=$dest_dir/IPKG_BUILD.$$
  mkdir $tmp_dir
  
  (cd $pkg_dir/data; find . -type f -print0 | xargs -0 md5sum ) > $pkg_dir/$CONTROL/md5sums
  if [ ! -f "$pkg_dir/files.txt" ]; then
  (cd $pkg_dir/data; find . -type f -print0 |xargs -0 grep '' -l) >$pkg_dir/files.txt
  fi
  # tar -C $pkg_dir/data -cf $tmp_dir/data.tar -T $pkg_dir/files.txt -h --verify
  tar -C $pkg_dir/data -cf $tmp_dir/data.tar . --verify
  gzip -f $tmp_dir/data.tar
  tar -C $pkg_dir/$CONTROL -czf $tmp_dir/control.tar.gz .
  
  echo "2.0" > $tmp_dir/debian-binary
  
  pkg_file=$dest_dir/${pkg}_${version}_${arch}.ipk
  #tar -C $tmp_dir -czf $pkg_file ./debian-binary ./data.tar.gz ./control.tar.gz
  (cd $tmp_dir ;ar -qc $pkg_file ./debian-binary ./data.tar.gz ./control.tar.gz ; mv $pkg_file ../)
  rm $tmp_dir/debian-binary $tmp_dir/data.tar.gz $tmp_dir/control.tar.gz
  rmdir $tmp_dir
  
  echo "Packaged contents of $pkg_dir into $pkg_file"
  这个脚本我对它作过一处非常细微的修改,旧的脚本中在打包data.tar.gz时,对软连接和硬连接是将连接指向的文件进行打包的。而实际上我们没有必要这样做,我们可以直接将连接以原始方式打包到ipk的data.tar.gz中,这是ipk包允许的。而且实际上webOS系统中原本有好多包本来就是带有软连接的,如果不做这个修改,后面我们就不能正确的将系统全部打包回ipk。

  好了,有了这个脚本,我们就可以自制ipk包了。首先建立一个包的目录,通常我们以包名来命名,然后在其下建立两个目录,分别为CONTROL和data,注意大小写。

  CONTROL目录下放control.tar.gz解压之后的内容。其中不必包含md5sums,即使包含在打包时也会重新生成,因此不必担心md5sums的正确性。

  data目录下放data.tar.gz解压之后的内容。注意它是相对于/的,里面的内容要包含相对于/的路径。另外,即使你希望这些内容被安装到/media/cryptofs/apps,也不要把这个路径建立到data目录下,这个路径是在安装时才决定的。

  之后你可以对这两个目录下的内容进行修改编辑,添加删除内容都可以。修改完毕之后,退回到这个包目录的上级目录下,然后将其拥有者和用户组都改为root(对于普通包是这样的,对于系统包来说,我们应该在解压系统包时就保留系统包的用户组,在修改时不要变更原来文件的用户组)。最后执行ipkg-build 包名,就可以重新打包生成修改之后的ipk了。

热心网友 时间:2023-10-25 10:15

ipk的安装对于大多数用户来说都是使用preware、WebOS Quick Install、Internalz Pro来安装程序的。如果不考虑postinst脚本,那么使用这些工具安装的文件都是相对于/media/cryptofs/apps目录进行安装的。如果直接使用不带-o参数的ipkg install命令安装的话,那么安装的文件都是相对于/目录的。也就是说ipk包中实际上并不包含相对于那个路径进行安装的信息。安装到哪儿只跟安装的方式有关。
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
ef英语哪个好 EF英孚英语培训怎么样? 英孚英语好不好 EF英孚教育到底好不好 大佬们,麦芒7和荣耀10那个值得入手?2500以下的机子还有啥好推荐的么... 介绍几款2500元以前的手机 像素一定要高 其他的不做要求 近期想入手一部安卓手机,价格2200到2500左右…买HTC desire Z还是 三星... 笔记本忘记开机密码怎么办急死了 笔记本电脑屏幕开机锁忘记密码 怎么办?急死了 华硕笔记本电脑开机密码忘记了怎样找回?系统是Windows 7旗舰版... 如何提取ipk包,如何打包 怎样在Ubuntu做语句循环 linux 下压缩tar.bz2 西门子冰箱后盖拆解图 魅蓝3S后盖怎么打开 电脑,橡皮,尺子用英文怎么拼 尺子和橡皮的英文发音相同吗 尺子和象皮擦的英语单词是什么 劳动合同到期后公司可以不续签吗 用英语怎么读铅笔尺子橡皮蜡笔 合婚中上婚姻怎么样 合同到期公司不续签该怎样补偿 我有一把尺子/一块橡皮。英语翻译语音 合同到期不续签公司要赔偿吗? 什么是上等婚 劳动合同到期后单位可以不续签吗 全身皮肤痒,抓后起小疙瘩是什么问题? 合同到期用人单位不续签 下等婚五鬼是什么意思 手,尺子,房子的英语发音不同的哪一个 身上长了好多这种小疙瘩,很痒!是什么原因呢? 在linux怎么解压文件? 如何提取ipk文件 我在解压hadoop压缩包的时候遇到这问题怎么办? ipkg包里面有没有检测系统,硬盘温度的软件 linux下压缩命令 谁知道怎么弄? 英文名(女)越多越好 超额部分老板应该占多少比例 公司利润分配一般是什么样的? 很长时间没洗头,现在有头螨了,用什么能去除头螨? 去除头螨,用什么药,或者方法最好 奖金分配方案 股权激励有几种形式啊?具体是哪些呢? 私募一姐王茹远过往业绩怎么样? 股权激励主要有哪些方式? 普通人如何成为基金经理 举重公斤级是什么意思? 某厂向国家承包,一年上缴利润1500万元,所得的超额利润国家与工厂按7:3分配 顺丰速递哈尔滨网点电话 举重比赛每个公斤级要求的体重范围 江西有哪些革命老区?