Problema ao obter o busybox switch_root para funcionar

5

Estou trabalhando em um sistema ARM Linux integrado que inicializa usando o initramfs. (Veja alguns antecedentes de algumas anteriores perguntas , se você estiver interessado.) Até agora, obrigado em parte à ajuda recebida aqui, eu posso inicializar o kernel via TFTP com um initramfs embutido. O driver MMC detecta um cartão SD contendo um novo sistema de arquivos raiz, que eu posso montar. No entanto, não consigo dar o passo final, usando o busybox switch_root para mudar para o sistema de arquivos no cartão SD, para trabalhar.

No prompt do initramfs, acho que isso deve fazer o kernel mudar para o novo sistema de arquivos:

switch_root -c /dev/console /mnt/root /sbin/init.sysvinit 

No entanto, isso só faz o busybox (para o qual switch_root é aliado) imprimir sua página de manual, assim:

/ # switch_root -c /dev/console /mnt/root /sbin/init.sysvinit 
BusyBox v1.17.4 (2010-12-08 17:01:07 EST) multi-call binary.

Usage: switch_root [-c /dev/console] NEW_ROOT NEW_INIT [ARGS]

Free initramfs and switch to another root fs:
chroot to NEW_ROOT, delete all in /, move NEW_ROOT to /,
execute NEW_INIT. PID must be 1. NEW_ROOT must be a mountpoint.

Options:

-c DEV  Reopen stdio to DEV after switch

Eu acho que a opção -c está correta, já que é a mesma que está contida no exemplo, e / dev / console existe.

/ # ls -l /dev
total 0
crw-r--r--    1 0        0           5,   1 Jan  1 00:28 console
brw-r--r--    1 0        0           7,   0 Dec 21  2010 loop0
brw-r--r--    1 0        0         179,   0 Dec 21  2010 mmcblk0
brw-r--r--    1 0        0         179,   1 Dec 21  2010 mmcblk0p1
brw-r--r--    1 0        0         179,   2 Dec 21  2010 mmcblk0p2
brw-r--r--    1 0        0         179,   3 Dec 21  2010 mmcblk0p3
brw-r--r--    1 0        0         179,   4 Dec 21  2010 mmcblk0p4

/ mnt / root também existe.

/ # ls /mnt/root
bin         etc         linuxrc     mnt         sys         var
boot        home        lost+found  proc        tmp
dev         lib         media       sbin        usr

O executável do init existe:

/ # ls -lh /mnt/root/sbin/
<snip>
lrwxrwxrwx    1 0        0             19 Dec 21  2010 init -> /sbin/init.sysvinit
-rwxr-xr-x    1 0        0          22.8K Dec 21  2010 init.sysvinit

Mas aqui está algo estranho:

/mnt/root/sbin # pwd
/mnt/root/sbin
/mnt/root/sbin # ls -l | grep init.sysvinit
lrwxrwxrwx    1 0        0               19 Dec 21  2010 init -> /sbin/init.sysvinit
-rwxr-xr-x    1 0        0            23364 Dec 21  2010 init.sysvinit
/mnt/root/sbin # ./init.sysvinit 
/bin/sh: ./init.sysvinit: not found
/mnt/root/sbin # /mnt/root/sbin/init.sysvinit 
/bin/sh: /mnt/root/sbin/init.sysvinit: not found

Isso é totalmente mistificador. Não tenho certeza de onde estou indo errado. Eu olhei para a fonte, que está em link

Não é apenas o executável init.sysvinit. Não consigo executar nada do cartão SD. Por exemplo:

/mnt/root/bin # ./busybox 
/bin/sh: ./busybox: not found
/mnt/root/bin # /mnt/root/busybox 
/bin/sh: /mnt/root/busybox: not found
/mnt/root/bin # ls -l | grep "2010 busybox"
-rwxr-xr-x    1 0        0           462028 Dec 21  2010 busybox

Alguém tem uma pista do que está errado aqui? Eu pensei que poderia ser algum problema com a montagem da placa noexec, mas acredito exec é o padrão, e eu tentei passar a opção exec explicitamente na montagem sem sucesso.

    
por pingswept 21.12.2010 / 04:10

2 respostas

12

A razão pela qual switch_root não está funcionando na linha de comando é este código no busybox:

    if (st.st_dev == rootdev || getpid() != 1) {
        // Show usage, it says new root must be a mountpoint
        // and we must be PID 1
        bb_show_usage();
    }

Você não é PID 1, então você está caindo para este bb_show_usage . A implicação é que o comando switch_root no script init initfts deve executar switch_root com exec . ou seja,

exec switch_root ...

O outro problema com os erros "não encontrados" é provável porque as bibliotecas compartilhadas necessárias pelos executáveis não foram encontradas, porque o sistema de arquivos raiz initramfs não as possui. Se você conseguir que switch_root trabalhe com exec , é provável que o erro "não encontrado" desapareça.

    
por 21.12.2010 / 05:26
1

switch_root -c /dev/console /mnt/root /mnt/root/sbin/init.sysvinit funcionou para mim. Eu tive o mesmo problema, mas switch_root -c /dev/console /mnt/root /sbin/init.sysvinit não funcionou.

Me desculpe Nenhum funcionou para mim.

Eu fiz um sistema de arquivos ext2 copiado busybox estaticamente construído com todos os seus softlinks. E o busybox tem um bit pegajoso (- permissões rwsr-sr-x). Eu tenho um / linuxrc e eu não tenho muito no diretório / etc /. E faço imagem do sistema de arquivos ext2 com o seguinte comando.

mkimage -C gzip -A ppc -O linux -T ramdisk -a 0x2000000 -n "ramdisk" -d initrd-ext2 initrd.img

Eu mantenho o initrd.img como um arquivo separado em / boot / e não faz parte do kernel.

O conteúdo do linuxrc é

#! / bin / sh (também tentou #! / bin / busybox sh)

mkdir -p /proc /dev /sys /mnt /tmp
mount -t proc proc /proc
mount -t sysfs sysfs /sys
mknod /dev/misc/rtc0 c 254 0
mdev -s
mkdir -p /new_root
mount /dev/mmcblk0p2 /new_root
exec switch_root -c /dev/console /new_root /sbin/init

Meu kernel é carregado corretamente e o initrd.img também é carregado e o linuxrc é executado, mas no final o switch_root fornece ajuda ao uso.

Mas o meu sistema continua a inicializar e carrega os novos rootfs. O seguinte é a seqüência.

RAMDISK: ext2 filesystem found at block 0
RAMDISK: Loading 10240KiB [1 disk] into ram disk... done.
VFS: Mounted root (ext2 filesystem) on device 1:0.
Starting initramfs boot...

Waiting 5 seconds for devices to settle...

kjournald starting.  Commit interval 5 seconds
EXT3 FS on mmcblk0p2, internal journal
EXT3-fs: mounted filesystem with writeback data mode.
BusyBox v1.21.0.git (2012-10-17 00:34:21 PDT) multi-call binary.

Usage: switch_root [-c /dev/console] NEW_ROOT NEW_INIT [ARGS]

Free initramfs and switch to another root fs:
chroot to NEW_ROOT, delete all in /, move NEW_ROOT to /,
execute NEW_INIT. PID must be 1. NEW_ROOT must be a mountpoint.

        -c DEV  Reopen stdio to DEV after switch

VFS: Mounted root (ext3 filesystem) on device 179:2.
Trying to move old root to /initrd ... /initrd does not exist. Ignored.
Unmounting old root
Trying to free ramdisk memory ... okay
Freeing unused kernel memory: 200k init
INIT: version 2.86 booting
Please wait: booting...
mount: sysfs already mounted or /sys busy
mount: according to mtab, sysfs is already mounted on /sys
Starting udev
udev: starting version 154
Root filesystem already rw, not remounting
Caching udev devnodes
  1. Meu ram é liberado depois de sair do initrd.img na sequência acima?

  2. E se eu não fizer switch_root no final do linuxrc e apenas colocar uma saída? Não vai liberar meu carneiro do meu antigo initg img.

por 25.10.2012 / 01:38