当前时区为 UTC + 8 小时



发表新帖 回复这个主题  [ 18 篇帖子 ]  前往页数 1, 2  下一页
作者 内容
1 楼 
 文章标题 : [原创人]从硬盘启动的 gnix_oag 文件
帖子发表于 : 2006-10-01 22:04 
头像

注册: 2005-05-19 18:38
帖子: 1991
地址: 湖南永州
送出感谢: 0 次
接收感谢: 1
代码:
#!/bin/sh

# set -e

export PATH=/root/usr/bin:/root/usr/sbin:/root/bin:/root/sbin:/usr/bin:/usr/sbin:/bin:/sbin

#iso文件的的挂载点
mountpoint=/iso_cdrom
mkdir -p $mountpoint
mkdir -p /cdrom
find_wyj=edgy #要找的文件夹

#overlay_method=unionfs
#if [ "${DPKG_ARCH}" = "ia64" ] || [ "${DPKG_ARCH}" = "hppa" ] || [ "${DPKG_ARCH}" = "sparc" ]; then
#    overlay_method=devmapper
#fi

#初始化用户名、用户全称、主机名
USERNAME=ubuntu
USERFULLNAME="Live session user"
HOST=ubuntu

[ -f /etc/casper.conf ] && . /etc/casper.conf

export USERNAME USERFULLNAME HOST

#验证 live cd 的映象
is_casper_path() {
    path=$1
    if [ -d "$path/casper" ]; then
        if [ "$(echo $path/casper/*.cloop)" != "$path/casper/*.cloop" ] ||
            [ "$(echo $path/casper/*.squashfs)" != "$path/casper/*.squashfs" ]; then
            return 0
        fi
    fi
    return 1
}

#得到全部磁盘分区的列表
subdevices() {
    sysblock=$1
    r=""
    for dev in "${sysblock}" "${sysblock}"/*; do
        if [ -e "${dev}/dev" ]; then
            r="${r} ${dev}"
        fi
    done
    echo ${r}
}

#获得环回(loop)设备
get_backing_device() {
   case "$1" in
            *.cloop)
                echo $(setup_loop "$1" "cloop" "/sys/block/cloop*")
         ;;
            *.squashfs)
                echo $(setup_loop "$1" "loop" "/sys/block/loop*")
                ;;
            *)
                panic "Unrecognized casper filesystem: $1"
                ;;
   esac
}

match_files_in_dir() {
    # Does any files match pattern $1 ?

    local pattern="$1"
    if [ "$(echo $pattern)" != "$pattern" ]; then
        return 0
    fi
    return 1
}

mount_images_in_directory() {
    directory="$1"
    rootmnt="$2"
    if match_files_in_dir "$directory/casper/*.cloop"; then
        # Let's hope there's just one matching *.cloop... FIXME
        setup_devmapper $(get_backing_device "$directory/casper/*.cloop") "$rootmnt"
    elif match_files_in_dir "$directory/casper/*.squashfs"; then
        setup_unionfs "$directory/casper" "$rootmnt"
    else
        :
    fi
}

#生成/dev的设备名
sys2dev() {
    sysdev=${1#/sys}
    echo "/dev/$(udevinfo -q name -p ${sysdev} 2>/dev/null|| echo ${sysdev##*/})"
}

#安装文件到环回设备
setup_loop() {
    local fspath=$1
    local module=$2
    local pattern=$3

    modprobe -Qb "$module"
    udevsettle
 
    for loopdev in $pattern; do
        if [ "$(cat $loopdev/size)" -eq 0 ]; then
            dev=$(sys2dev "${loopdev}")
            losetup "$dev" "$fspath"
            echo "$dev"
            return 0
        fi
    done
    panic "No loop devices available"
}

#获得文件系统的类别
get_fstype() {
    local FSTYPE
    local FSSIZE
    eval $(fstype < $1)
    if [ "$FSTYPE" != "unknown" ]; then
        echo $FSTYPE
        return 0
    fi
    /lib/udev/vol_id -t $1 2>/dev/null
}

#安装磁盘映象(可写入的)
setup_devmapper() {
    backdev="$1"
    rootmnt="$2"

    modprobe -Qb dm-mod
    COW_DEVICE=/dev/ram1
    COW_NAME="casper-cow"

    BACKING_FILE_SIZE=$(blockdev --getsize "$backdev")
    MAX_COW_SIZE=$(blockdev --getsize "$COW_DEVICE")
    CHUNK_SIZE=8 # sectors

    if [ -z "$COW_SIZE" -o "$COW_SIZE" -gt "$MAX_COW_SIZE" ]; then
        COW_SIZE=$MAX_COW_SIZE
    fi

    echo "0 $COW_SIZE linear $COW_DEVICE 0" | dmsetup create $COW_NAME

    echo "0 $BACKING_FILE_SIZE snapshot $backdev /dev/mapper/$COW_NAME p $CHUNK_SIZE" | \
        dmsetup create casper-snapshot
    if [ "$(get_fstype $backdev)" = "unknown" ]; then
        panic "Unknown file system type on $backdev"
    fi
    mount -t $(get_fstype "$backdev") /dev/mapper/casper-snapshot $rootmnt || panic "Can not mount /dev/mapper/casper/snapshot on $rootmnt"

    mkdir -p "$rootmnt/rofs"
    echo "0 $BACKING_FILE_SIZE linear $backdev 0" | dmsetup create casper-backing
    mount -t $(get_fstype "$backdev") /dev/mapper/casper-backing "$rootmnt/rofs"
}

#验证及获取挂载点的位置
where_is_mounted() {
    device=$1
    if grep -q "^$device " /proc/mounts; then
        grep "^$device " /proc/mounts | read d mountpoint rest
        echo $mountpoint
        return 0
    fi
    return 1
}

#查找可写入的 cow 设备
find_cow_device() {
    for sysblock in $(echo /sys/block/* | tr ' ' '\n' | grep -v loop); do
        for dev in $(subdevices "${sysblock}"); do
            devname=$(sys2dev "${dev}")
            if [ "$(/lib/udev/vol_id -l $devname 2>/dev/null)" = "casper-rw" ]; then
                echo "$devname"
                return
            elif [ "$(get_fstype ${devname})" = "vfat" ]; then
                mkdir -p /cow-backing
                if where_is_mounted ${devname} > /dev/null; then
                    mount -o remount,rw ${devname} $(where_is_mounted ${devname}) || panic "Remounting failed"
                    mount -o bind $(where_is_mounted ${devname}) /cow-backing || panic "Cannot bind-mount"
                else
                    mount -t $(get_fstype "${devname}") -o rw "${devname}" /cow-backing || panic "Cannot mount $devname on /cow-backing"
                fi

                if [ -e "/cow-backing/casper-rw" ]; then
                    echo $(setup_loop "/cow-backing/casper-rw" "loop" "/sys/block/loop*")
                    return 0
                else
                    umount /cow-backing
                fi
            fi
           
        done
    done
    return 1   
}

#安装联合文件系统 (可写入的
setup_unionfs() {
    image_directory="$1"
    rootmnt="$2"
    modprobe -Qb unionfs

    # run-init can't deal with this, but we're going to move all of these
    # away before it runs anyway.
    croot="/casper"

    # Let's just mount the read-only file systems first
    mkdir -p "${croot}"
    for image in "${image_directory}"/*.squashfs; do
        imagename=$(basename "${image}")
        backdev=$(get_backing_device "$image")
        fstype=$(get_fstype "${backdev}")
        if [ "${fstype}" = "unknown" ]; then
            panic "Unknown file system type on ${backdev} (${image})"
        fi
        mkdir -p "${croot}/${imagename}"
        mount -t "${fstype}" -o ro "${backdev}" "${croot}/${imagename}" || panic "Can not mount $backdev ($image) on ${croot}/${imagename}"
    done

    rofsstring=""
    for dir in $(mount -t squashfs | cut -d\  -f 3); do
        rofsstring="$dir=ro:$rofsstring"
    done
    rofsstring=${rofsstring%:}

if [ "$ubuntu_fs" ] ; then
    cow=$ubuntu_fs
else
    mkdir -p /cow
    mount -t tmpfs tmpfs /cow
    cow=/cow
fi   

    mount -t unionfs -o dirs=$cow=rw:$rofsstring unionfs "$rootmnt"

    for d in $(mount -t squashfs | cut -d\  -f 3); do
        mkdir -p "${rootmnt}/casper/${d##*/}"
        mount -o move "${d}" "${rootmnt}/casper/${d##*/}"
    done
   if [ "$ubuntu_fs" ] ; then
    mkdir -p "$rootmnt/ubuntu.fs"
    mount -o bind $cow "$rootmnt/ubuntu.fs"
   fi
    mkdir -p "$rootmnt/iso_cdrom"
    mount -o bind $mountpoint "$rootmnt/iso_cdrom"
}

#验证是否为usb磁盘
is_usb_device() {
    sysfs_path="${1#/sys}"
    if /lib/udev/path_id "${sysfs_path}" | grep -q "ID_PATH=(usb|pci-[^-]*-usb)"; then
        return 0
    fi
    return 1
}

#生成/fstab文件
make_fstab() {
#找所的硬盘及分区
cat /proc/partitions | tr -s "[\ ]" | cut -d\  -f5 | tr  "[\n]" "[ ]" > /dev_tmp
#开始生成fstab
msfscount=98   #ms文件系统计数值: 98对应B
for dev_name in $(cat /dev_tmp) ; do
   fstype=$(get_fstype "/dev/${dev_name}")
   case "$fstype" in
      reiserfs|minix|xfs|jfs|ext3|ext2|swap|ntfs|vfat)
      get_mountpoint
      mkdir -p ${getmountpoint}
      get_mountoptions
      echo "/dev/${dev_name} ${getmountpoint} ${fstype} ${getmountoptions} 0 0 " >> /fstab
      ;;
   esac
done
#找所有的光驱
for sysblock in $(echo /sys/block/* | tr ' ' '\n' | grep -v loop | grep -v ram); do
   hd_dev=$(echo "$(udevinfo -q name -p ${sysblock#/sys} 2>/dev/null || echo ${sysblock##*/})")
   if /lib/udev/cdrom_id /dev/${hd_dev} > /dev/null; then
      echo "/dev/${hd_dev} /media/${hd_dev} auto  noauto,user 0 0 " >> /fstab
      mkdir -p /media/${hd_dev}
   fi
done
rm /dev_tmp
}

#生成挂载点
get_mountpoint(){
getmountpoint=
case "$fstype" in
    ntfs*|vfat|msdos)
          msfscount=$(expr $msfscount + 1)
          getmountpoint=/media/`echo -e -n "\\x$(printf %x $msfscount)"`_win  ;;
    swap)   getmountpoint="none"  ;;
    *)    getmountpoint="/media/${dev_name}" ;;
esac
}

#生成挂载选项
get_mountoptions(){
getmountoptions=

case "$fstype" in
   vfat)  getmountoptions="umask=000,shortname=winnt,user,exec,utf8," ;;
   msdos) getmountoptions="umask=000,user,exec,utf8" ;;
   swap)  getmountoptions="defaults" ;;
   ntfs)  getmountoptions="umask=000,user,exec,utf8";;
   *)     getmountoptions="user,exec";;
esac
}

#搜索磁盘,找相关文件
find_file() {
modprobe -Qb loop
while read  hd_dev hd_mount_point hd_fstype hd_mount_options dump fcsk ; do
   case "$hd_fstype" in
      reiserfs|minix|xfs|jfs|ext3|ext2|ntfs|vfat)
      modprobe -Qb "$hd_fstype"
      mkdir -p /"${hd_mount_point##*/}"
      mount -t ${hd_fstype} -o "${hd_mount_options##*user,}" ${hd_dev} /"${hd_mount_point##*/}" || continue
      find_swap_fs
      if [ ! -d /"${hd_mount_point##*/}/$find_wyj" ];then
            umount /"${hd_mount_point##*/}"
      fi
      find_iso
      find_ubuntu_fs
      if [ "$findiso" -a "$findubuntufs" -a "$findswapfs" ];then   #三个文件都没有在这个分区上,就卸载它
         umount /"${hd_mount_point##*/}"
         continue
      fi
      if [ "$iso_cdrom" -a "$ubuntu_fs" -a "$swap_fs" ];then      #三个文件都找到,就返回
         return
      fi
   ;;
   esac
done
}

#找live cd iso 映象
find_iso() {
if [ -z "$iso_cdrom" ];then
      for iso in $(echo /"${hd_mount_point##*/}"/$find_wyj/*.[iI][sS][oO] ) ; do
         mount -t iso9660 -o loop $iso $mountpoint || continue
         if is_casper_path $mountpoint; then
              iso_cdrom=$mountpoint
            findiso=
            return
         else
            umount $mountpoint
         fi
      done
fi
findiso=no
}

#找可写入的ubuntu.fs文件系统
find_ubuntu_fs() {
if [ -z "$ubuntu_fs" ];then
   if [ -f /"${hd_mount_point##*/}"/$find_wyj/ubuntu.fs ]; then
      ubuntufstype=$(get_fstype /"${hd_mount_point##*/}"/$find_wyj/ubuntu.fs )
      mkdir -p /ubuntu_fs
      if mount -t $ubuntufstype -o rw,loop /"${hd_mount_point##*/}"/$find_wyj/ubuntu.fs /ubuntu_fs ; then
         ubuntu_fs=/ubuntu_fs
         findubuntufs=
         return
      fi
   fi     
   case $hd_fstype in
   reiserfs|minix|xfs|jfs|ext3|ext2)
      if [ -d /"${hd_mount_point##*/}"/$find_wyj/ubuntu.fs ]; then
         ubuntu_fs=/"${hd_mount_point##*/}"/$find_wyj/ubuntu.fs
         findubuntufs=
         return
      fi
   ;;
   esac     
fi
findubuntufs=no
}

#找 swap 文件
find_swap_fs() {
if [ -z "$swap_fs" ];then
   if [ -f /"${hd_mount_point##*/}"/swap.fs ]; then
      swap_fs=$hd_mount_point
      findswapfs=
      return
   fi
fi
findswapfs=no
}

#设定usplash 延时
set_usplash_timeout() {
    if [ -x /sbin/usplash_write ]; then
        /sbin/usplash_write "TIMEOUT 120"
    fi
}

#挂载 root 文件系统
mountroot() {
    exec 6>&1
    exec 7>&2
    exec > casper.log
    exec 2>&1
   
    set_usplash_timeout
    [ "$quiet" != "y" ] && log_begin_msg "Running /scripts/casper-premount"
    run_scripts /scripts/casper-premount
    [ "$quiet" != "y" ] && log_end_msg

    # Needed here too because some things (*cough* udev *cough*)
    # changes the timeout

    set_usplash_timeout

    for i in 0 1 2 3 4 5 6 ; do
    rm /fstab
    make_fstab

        find_file < /fstab
        if [ "${iso_cdrom}" ]; then
            break
        fi
        sleep 2
    done
    if [ "$?" -gt 0 ]; then
        panic "Unable to find a medium containing a live file system"
    fi
   
    mount_images_in_directory "$iso_cdrom" "$rootmnt"
    log_end_msg

 #配置系统
if [ ! -e $rootmnt/etc/gnix.oag@gmail.com ];then
    touch  $rootmnt/etc/gnix.oag@gmail.com

    maybe_break casper-bottom
    [ "$quiet" != "y" ] && log_begin_msg "Running /scripts/casper-bottom"

    run_scripts /scripts/casper-bottom
   
      mv  /media/*  $rootmnt/media/
       #配置 swap 文件
     if [ "$swap_fs" ]; then
      mount -o bind  "${swap_fs##*/}"   $rootmnt$swap_fs
cat >> /fstab  <<EOF
$swap_fs/swap.fs  swap  swap  defaults  0  0
EOF
    fi

    cat /fstab >> $rootmnt/etc/fstab

#修正时间相差8小时
chroot /root  sed -i -e "s/^UTC=.*\$/UTC=no/" /etc/default/rcS
 
 #不显示桌面上的分区图标
chroot /root sudo -u "$USERNAME" gconftool-2 -s -t bool /apps/nautilus/desktop/volumes_visible false
    [ "$quiet" != "y" ] && log_end_msg
fi
    exec 1>&6 6>&-
    exec 2>&7 7>&-
    cp casper.log "${rootmnt}/var/log/"
}


最后由 gnix_oag 编辑于 2006-11-17 13:55,总共编辑了 6 次

页首
 用户资料  
 
2 楼 
 文章标题 :
帖子发表于 : 2006-10-04 9:18 

注册: 2005-10-07 18:55
帖子: 116
送出感谢: 0 次
接收感谢: 0 次
kernel (hd0,0)/boot/vmlinuz boot=gnix_oag ramdisk_size=1048576 root=/dev/ram rw quiet splash debian-installer/locale=zh_CN

红色的两句是什么意思?


页首
 用户资料  
 
3 楼 
 文章标题 :
帖子发表于 : 2006-10-04 12:23 
头像

注册: 2005-05-19 18:38
帖子: 1991
地址: 湖南永州
送出感谢: 0 次
接收感谢: 1
boot=gnix_oag 表示用我上面的这个文件

debian-installer/locale=zh_CN 是设定本地语言


页首
 用户资料  
 
4 楼 
 文章标题 :
帖子发表于 : 2006-10-05 17:06 
头像

注册: 2005-05-19 18:38
帖子: 1991
地址: 湖南永州
送出感谢: 0 次
接收感谢: 1
发现个问题,找到的光盘,没有没有建相关的文件夹。

#找所有的光驱
for sysblock in $(echo /sys/block/* | tr ' ' '\n' | grep -v loop | grep -v ram); do
hd_dev=$(echo "$(udevinfo -q name -p ${sysblock#/sys} 2>/dev/null || echo ${sysblock##*/})")
if /lib/udev/cdrom_id /dev/${hd_dev} > /dev/null; then
echo "/dev/${hd_dev} /media/${hd_dev} auto noauto,user 0 0 " >> /fstab
mkdri -p /media/${hd_dev}
fi
done


页首
 用户资料  
 
5 楼 
 文章标题 :
帖子发表于 : 2006-10-15 17:57 

注册: 2006-10-15 17:56
帖子: 2
送出感谢: 0 次
接收感谢: 0 次
这个功能和它自带的
https://help.ubuntu.com/community/LiveC ... eaf5c5a90c

有什么不同呀?


页首
 用户资料  
 
6 楼 
 文章标题 :
帖子发表于 : 2006-11-17 13:50 
头像

注册: 2005-05-19 18:38
帖子: 1991
地址: 湖南永州
送出感谢: 0 次
接收感谢: 1
修正时间总是相差8小时

chroot $rootmnt sed -i -e "s/^UTC=.*\$/UTC=no/" /etc/default/rcS


页首
 用户资料  
 
7 楼 
 文章标题 :
帖子发表于 : 2006-11-17 13:58 
头像

注册: 2005-05-19 18:38
帖子: 1991
地址: 湖南永州
送出感谢: 0 次
接收感谢: 1
更改 make_fstab 的位置 ,这样也就可以找到 usb 盘上的 iso (usb初始化要5秒钟,)
for i in 0 1 2 3 4 5 6 ; do
rm /fstab
make_fstab

find_file < /fstab
if [ "${iso_cdrom}" ]; then
break
fi
sleep 2
done


页首
 用户资料  
 
8 楼 
 文章标题 :
帖子发表于 : 2006-11-17 14:07 
头像

注册: 2005-08-14 21:55
帖子: 58428
地址: 长沙
送出感谢: 4
接收感谢: 272
引用:
for i in 0 1 2 3 4 5 6
nnd,真是偷懒阿。没程序的风格。 :lol:


_________________
● 鸣学


页首
 用户资料  
 
9 楼 
 文章标题 :
帖子发表于 : 2006-11-17 15:37 

注册: 2006-09-15 16:37
帖子: 30
送出感谢: 0 次
接收感谢: 0 次
楼主,小弟有几个问题想请教:
1,ubuntu.fs是怎么做的啊,是用dd吗,可我做的时候总出现段错误?
2,我想把系统放在U盘上,那两个fs文件放在硬盘上,不知道还需要做哪些工作,我是不是要把ISO文件放在U盘上,然后装个grub,把那两个fs文件放在硬盘上就可以了
还望不吝赐教啊,谢谢


页首
 用户资料  
 
10 楼 
 文章标题 :
帖子发表于 : 2006-11-17 19:28 
头像

注册: 2005-05-19 18:38
帖子: 1991
地址: 湖南永州
送出感谢: 0 次
接收感谢: 1
1,ubuntu.fs 是从colinux 上下载的。
2,这样是可以的,不过grub,不好用,换一台机子就可能找不到vmlinux 等了,
我试了一下syslinux 来引导,可也太慢了,载入 vmlinuz 要30秒,载入initrd.gz要一分多钟。


页首
 用户资料  
 
11 楼 
 文章标题 :
帖子发表于 : 2006-11-18 1:41 

注册: 2006-09-15 16:37
帖子: 30
送出感谢: 0 次
接收感谢: 0 次
1,可以给出下载连接吗,另外我有一个实现的思路,讨论一下吧
sudo -s
mkdir cow_fs
cd cow_fs
dd if=/dev/zero of=fs_old bs=1M count=2048
mkfs -t ext2 fs_old(不知道你的文件是什么文件系统,请说明一下,两外不同的文件系统有没有关系呢)
bzip2 fs_old
rm -f fs_old
这里我有两点疑问,首先,我用这种方法做了一个256M的只有2.1K,而你的文件是6.6K,其次,我如果用mksquashfs做的话,最后只有366B

对于swap_fs,我不知道能不能用这种方法做,如果能应该做成什么文件系统呢

2,我看到有个兄弟把系统放到移动硬盘的,我还没有试,他不就是把grub装到移动硬盘里了吗,你说他的方法也对硬件有限制吗,你能说一下为什么换一台机子就可能找不到vmlinux吗,速度慢的话可不可以用DOM卡代替,它是走IDE接口的FLASH存储设备,现在LIVECD很多是用syslinux引导的


页首
 用户资料  
 
12 楼 
 文章标题 :
帖子发表于 : 2006-11-18 1:45 

注册: 2006-09-15 16:37
帖子: 30
送出感谢: 0 次
接收感谢: 0 次
你说如果不用swap_fs可以吗,为什么(问题是不是太多了,见笑了,因为我对兄弟的大作很感兴趣)


页首
 用户资料  
 
13 楼 
 文章标题 :
帖子发表于 : 2006-11-18 7:59 
头像

注册: 2005-05-19 18:38
帖子: 1991
地址: 湖南永州
送出感谢: 0 次
接收感谢: 1
1,这样做是可以的,但有点我就不清楚,那个10G或20G的不是要个这么大的空间才能做,
swap_fs也可以这么做。
2,Grub 它表示硬盘用的是第几个硬盘,U盘在你的机子上可能是第2个,但在别人的机子上可能是第一个或第3个,这样 就更改配置文件才能用,而syslinux 就不会这样,
我讲的速度慢不是usb 慢,而是syslinux引导的时候慢,引导完后就还可以,正在找什么原因。
3,swap_fs是用来做虚拟内存的,内存大就可以不要了


页首
 用户资料  
 
14 楼 
 文章标题 :
帖子发表于 : 2006-11-18 9:33 

注册: 2006-09-15 16:37
帖子: 30
送出感谢: 0 次
接收感谢: 0 次
比如我想要最后可以保存40G的数据,你是说创建ubuntu_fs的时候不用指定40G大小?另外,我觉得把ubuntu_fs做成squashfs更好,这样以后如果存储的数据已经是40G还想存的话,可以合并两个ubuntu_fs文件

那用这种方法做swap_fs的时候怎么指定文件系统呢,也就是说mkfs -t后面的参数应该是什么呢


最后由 wawxdyy 编辑于 2006-11-18 9:40,总共编辑了 1 次

页首
 用户资料  
 
15 楼 
 文章标题 :
帖子发表于 : 2006-11-18 9:34 

注册: 2006-09-15 16:37
帖子: 30
送出感谢: 0 次
接收感谢: 0 次
关于第二个问题是跟主版有关系吗


页首
 用户资料  
 
显示帖子 :  排序  
发表新帖 回复这个主题  [ 18 篇帖子 ]  前往页数 1, 2  下一页

当前时区为 UTC + 8 小时


在线用户

正在浏览此版面的用户:没有注册用户 和 3 位游客


不能 在这个版面发表主题
不能 在这个版面回复主题
不能 在这个版面编辑帖子
不能 在这个版面删除帖子
不能 在这个版面提交附件

前往 :  
本站点为公益性站点,用于推广开源自由软件,由 DiaHosting VPSBudgetVM VPS 提供服务。
我们认为:软件应可免费取得,软件工具在各种语言环境下皆可使用,且不会有任何功能上的差异;
人们应有定制和修改软件的自由,且方式不受限制,只要他们自认为合适。

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
简体中文语系由 王笑宇 翻译