选择要自动启动的 QNX 分区

问题描述 投票:0回答:1

我目前有一个带有闪存卡的嵌入式设备,该设备有 3 个 QNX 6.5.0SP1 分区 - 两个可引导分区(fs 类型 79),一个数据分区(fs 类型 78)。我想以编程方式选择启动这两个可启动分区中的哪一个,基于数据分区上的某种标志(可能是一个

touch
'd 文件),在关闭之前由用户交互设置。这可能吗?理想情况下,最终结果是将所选分区的文件系统在启动后安装到根目录。

我尝试修改

.boot
文件,但我相信在执行交给
.boot
时分区已经启动。我相信我需要修改 IPL,但我不确定如何在 IPL 期间从任何文件系统读取。

operating-system embedded rtos qnx
1个回答
0
投票

最简单的解决方案是标记“活动”可启动分区,确保它是唯一一个带有

.diskroot
文件的分区,指示
diskboot
将其安装为
/
。切换过程是:使用
fdisk boot
将新的根分区标记为可启动;然后
mv /.diskroot
就可以了。

如果严格要求可启动分区不可写,则需要为系统设计一个替换启动脚本来启动关键驱动程序并进行自己的安装,因为

diskboot
不支持复杂的安装行为(它不支持重复的 .diskroot 安装点)。您可以使用
mkifs
将更新后的脚本链接到 .boot 文件的替换版本。

关键参考文档:

最后,作为一个优势,我可以提供这个 shell 脚本“fsscan”,我的公司在 QNX 6.3 天时曾用于此目的。该脚本查找具有“.bootkey”文件的分区,该文件与 IFS 中包含的“bootkey”文件相匹配;该文件的内容是简短版本和日期戳。这让我们选择一个启动分区,除了

fdisk boot
,它会找到并挂载匹配的根分区。

#/proc/boot/sh

# fsscan for QNX - scans for and mounts filesystems
# includes analysis of .diskroot for QNX filesystems for use at boot.

# Options
do_mount=0
build_fstab=1
parse_diskroot=0
commit_string=""
keyfile="/proc/boot/bootkey"

## Parse commandline
while getopts "mndck:" opt ; do
    case $opt in
        m)
            do_mount=1
        ;;
        n)
            build_fstab=0
        ;;
        d)
            parse_diskroot=1
        ;;
        k)
            keyfile="$OPTARG"
        ;;
        c)
            commit_string="commit=none"
        ;;
    esac
done

if [ -r "$keyfile" ]; then
    keydata=`cat $keyfile`
else
    keyfile=""
fi    


echo "Scanning available disk partitions..."

if [ "$build_fstab" -eq 1 ]; then
    echo "# fstab build by fsscan on `date`" > /etc/fstab
fi

# Get QNX devices
# We use two passes to figure out what to do.  First pass pre-mounts devices 
# and locates .bootkey, second pass manages other .diskroots.


UD=`ls /dev/ud*t79 /dev/ud*t78 /dev/ud*t77 2>/dev/null`
HD=`ls /dev/hd*t79 /dev/hd*t78 /dev/hd*t77 2>/dev/null`

QDEVS="$UD $HD"

# First pass
did_mount=""
was_mounted=""
for device in $QDEVS; do
    disk=`echo $device | sed -e "s/\/dev\/[hu]d\(.*\)t7[789]/\1/"`  
    type=`echo $device | sed -n -e "s/\/dev\/\([hu]\)d.*t7[789]/\1/p"`  
    id=`echo $device | sed -n -e "s/\/dev\/[hu]d.*t\(7[789]\)/\1/p"`    

    mountopts="rw"
    if [ ! -z "$commit_string" ]; then
        mountopts="$mountopts,$commit_string"
    fi
    
    # Check if already mounted
    mountpt=`df $device | awk "\\$1 == \"$device\" {print \\$6}"`

    is_mounted=0
    
    if [ -z "$mountpt" ]; then                
        num=$((80 - $id))
        mountpt="/fs/${type}d$disk-qnx4-$num"       
        
        if [ "$do_mount" -eq 1 ]; then 
            
            echo "Found QNX filesystem at $device, mounting as $mountpt"        
            mount -t qnx4 -o $mountopts $device $mountpt
            is_mounted=1
            did_mount="$did_mount $device"
        fi;
    
    else
        is_mounted=1        
        was_mounted="$was_mounted $device"        
        echo "Found QNX filesystem at $device already mounted as $mountpt"
    fi
    
    if [ "$is_mounted" -eq 1 ]; then         
        if [ -n "$keyfile" -a "$parse_diskroot" -eq 1 -a -r $mountpt/.diskroot -a -r $mountpt/.bootkey ]; then
            # Check boot key.
            fskeydata=`cat $mountpt/.bootkey`
            if [ "$keydata" = "$fskeydata" ]; then
                # Handle diskroot RIGHT NOW
                diskroot=`awk 'BEGIN { mp = "/" }
(NR == 1) && /\// { mp = $0; }
/^[ \t]*mount[ \t]*=/ { split($0,parts,/=/); mp = parts[2]; gsub(/^[ \t]*/,"",mp); gsub(/[ \t]*$/,"",mp);  }
END { print mp; }' <$mountpt/.diskroot`

#                   echo "$device: Diskroot mountpoint is '$diskroot'"                      
                
                if [ -z "$diskroot" ]; then             
                    diskroot="/"
                fi
                
                # Check for existing partition there
                if df $diskroot | awk "\$6 != \"$diskroot\" {exit 0} {exit 1}"; then
                    echo "Relocating QNX filesystem with matching key at $device to $diskroot"
                    umount $mountpt
                    if [ "$do_mount" -eq 1 ]; then
                        mount -t qnx4 -o $mountopts $device $diskroot
                    fi
                    mountpt="$diskroot"
                fi                            
            fi                
        fi;   
    else
            echo "Found QNX filesystem at $device, mountable as $mountpt"                       
    fi    
    
done;

#echo "Did mount: '$did_mount'   Was mounted: '$was_mounted'"

# Second pass
for device in $QDEVS; do
    disk=`echo $device | sed -e "s/\/dev\/[hu]d\(.*\)t7[789]/\1/"`  
    type=`echo $device | sed -n -e "s/\/dev\/\([hu]\)d.*t7[789]/\1/p"`  
    id=`echo $device | sed -n -e "s/\/dev\/[hu]d.*t\(7[789]\)/\1/p"`    

    mountopts="rw"
    if [ ! -z "$commit_string" ]; then
        mountopts="$mountopts,$commit_string"
    fi
    
    # Check if already mounted
    mountpt=`df $device | awk "\\$1 == \"$device\" {print \\$6}"`

    if echo $was_mounted | grep -q $device || echo $did_mount | grep -q $device; then
        # Process diskroot
        #echo "Considering $device for diskroot"
        # Read .diskroot
        if [ "$parse_diskroot" -eq 1 -a -r $mountpt/.diskroot ]; then
            diskroot=`awk 'BEGIN { mp = "/" }
(NR == 1) && /\// { mp = $0; }
/^[ \t]*mount[ \t]*=/ { split($0,parts,/=/); mp = parts[2]; gsub(/^[ \t]*/,"",mp); gsub(/[ \t]*$/,"",mp);  }
END { print mp; }' <$mountpt/.diskroot`

#           echo "$device: Diskroot mountpoint is '$diskroot'"                      
            
            if [ -z "$diskroot" ]; then             
                diskroot="/"
            fi
            
#           echo "Using '$diskroot' for $device"                    
                        
            # Check for existing partition there
            if df $diskroot | awk "\$6 != \"$diskroot\" {exit 0} {exit 1}"; then
                echo "Relocating QNX filesystem at $device to $diskroot"
                echo "umount $mountpt"
                umount $mountpt
                if [ "$do_mount" -eq 1 ]; then
                    echo "mount -t qnx4 -o $mountopts $device $diskroot"                
                    mount -t qnx4 -o $mountopts $device $diskroot
                fi
                mountpt="$diskroot"
            fi              
        fi                  
    else
        # Check is now mounted == bootkey
        if [ -z "$mountpt" ]; then                
            num=$((80 - $id))
            mountpt="/fs/${type}d$disk-qnx4-$num"
        fi
    fi

    if [ "$build_fstab" -eq 1 ]; then
        echo "$device   $mountpt    qnx4    $mountopts  0   0" >> /etc/fstab
    fi;
done;                   



# Grab DOS devices.
lastdisk=""
for id in 1 4 6 11 12; do
    for device in `ls /dev/hd*t$id /dev/hd*t$id.* /dev/ud*t$id /dev/ud*t$id.* 2>/dev/null`; do
        disk=`echo $device | sed -e "s/\/dev\/\([hu]d.*\)t$id.*/\1/"`   

        # Check if already mounted
        mountpt=`df $device | awk "\\$1 == \"$device\" {print \\$6}"`
        mountopts="rw"

        
        if [ -z "$mountpt" ]; then                
            is_mounted=0
            
            # Find mountpoint
            if [ "X$lastdisk" != "X$disk" ]; then
                lastdisk="$disk"
                num=0
            fi
            
            while [ -z "$mountpt" ]; do
                num=$(($num + 1))
                mountpt="/fs/$disk-dos-$num"
                if [ -e "$mountpt" ]; then
                    mountpt=""
                fi
            done;

            if [ "$do_mount" -eq 1 ]; then
                echo "Found DOS filesystem at $device, mounting as $mountpt"
                mount -t dos -o $mountopts $device $mountpt
            else
                echo "Found DOS filesystem at $device, mountable as $mountpt"
            fi
                                
        else
            echo "Found DOS filesystem at $device, already mounted as $mountpt"        
        fi
        
        if [ "$build_fstab" -eq 1 ]; then
            echo "$device   $mountpt dos    $mountopts  0   0" >> /etc/fstab
        fi      
    done;
done;

    
echo "Partition scan complete."

注意:此脚本需要完整的 shell 和一些 UNIX 文本处理实用程序,才能包含在 .boot IFS 中。 QNX 努力使其默认 IFS 尽可能小;这不是我们应用程序的限制。

mount
umount
sleep
sh
awk
sed
ls
cat
echo
df
grep
© www.soinside.com 2019 - 2024. All rights reserved.