mozilla 发表于 2004-12-9 18:47:33

在内核了想往ramdisk里写点东西,但不让写.

我手上有一块板,但接不了任何存储设备,板上只有一个2M的ROM,有一部分已经放了bi o s 程序,剩下部分刚好放一个内核,所以我想把根文件系统做到内核里,方法就是先用genromfs生成根文件系统的镜像,然后把它转换成字符数组放在一个头文件里,然后在do_mounts.c里包含这个头文件,然后在mount_root()里加代码,把这些数据写到ramdisk里,ramdisk是4M,但碰到点问题,ramdisk能打开,但写不进去任何数据.

static void __init write_fs_to_ram(void)
{
    int ram_fd;
    int ret;

//    ret=create_dev("/dev/ram", MKDEV(RAMDISK_MAJOR, 0), NULL);
//    printk("## RAMDISK: create_dev return %d\n",ret);
    ram_fd=open("/dev/ram",O_RDWR,0);
    if(!ram_fd)
    {
      printk("## RAMDISK: cannot open /dev/ram\n");
    }
    else
    {
      int count=0;
      int i=0;
      unsigned char *p=rootfs_data;
      printk("## RAMDISK: open /dev/ram successfully\n");
      for(i=0;i<1234;i++)
      {
            ret=write(ram_fd,p,512);
            p=p+512;
            count=count+ret;
      }
      printk("## RAMDISK: total written %d bytes\n",count);
      close(ram_fd);
    }
}
    //end



然后在mount_root()里调用这个函数.
运行结果是write返回的都是-1.

另外create_dev返回0是否表示设备文件已经成功生成?

suowei1979 发表于 2004-12-10 10:04:59

是读写权限问题?

kakuyou 发表于 2004-12-10 12:26:56

内核中操作文件不能用普通程序那样的/dev/ram的形式。那个形式的意思是根已经mount了,才能顺着根找dev目录,再找ram文件。

内核中必须直接用inode来操作文件,另外,把那个设备mount成根可以通过内核的启动参数来指定。

我认为不可能改内核的某个文件来mount根,因为你不能确定所有的设备是否已经初始化完了,也就是那个设备是否可以使用。

我想好好参考一下initrd的使用也许会有帮助。

参看一下模块是如何访问设备文件的,由于模块是在内核启动完后装载入内核的,所以尽管它是内核的一部分,但可以认为所有的内核资源都已经可以使用。
http://www.tldp.org/LDP/lkmpg/2.4/html/x856.html

呵呵,强调一句,偶是纸上谈兵,必须要请教有实际经验的高手才是万全之策。

mozilla 发表于 2004-12-10 15:50:57

我改变了一下根文件系统的创建方式,不直接去写/dev/ram,而是把/dev/ram先mount上来,再在里面创建根文件系统所需的基本文件.

static void __init create_my_rootfs(void)
{
    int busybox_fd;
    int inittab_fd;
    int passwd_fd;
    int group_fd;
    int rcS_fd;
    int test_fd;
    int i;
    char *busybox_cmd[]={"/bin/sh","/bin/login","/bin/ls","/sbin/init","/sbin/getty",NULL};
   
    int ret;
    ret=sys_mknod("/dev/ram", S_IFBLK|0755, MKDEV(RAMDISK_MAJOR, 0));
    ret=sys_mkdir("/myrootfs",0755);
    sys_chdir("/myrootfs");
    ret=sys_mount("/dev/ram",".","ramfs",0,NULL);
    sys_umount("/dev", 0);
    sys_mount(".", "/", NULL, MS_MOVE, NULL);
    sys_chroot(".");
    sys_mkdir("/dev",0755);
    sys_mkdir("/sbin",0755);
    sys_mkdir("/etc",0755);
    sys_mkdir("/etc/init.d",0755);
    sys_mkdir("/proc",0755);
    sys_mkdir("/tmp",0755);
    sys_mkdir("/var",0755);
    sys_mkdir("/root",0755);
    sys_mknod("/dev/console", S_IFCHR|0600, MKDEV(5, 1));
    sys_mknod("/dev/ttyS0", S_IFCHR|0600, MKDEV(4, 64));
    test_fd=open("/etc/test", O_CREAT | O_RDWR ,S_IRWXU);
    inittab_fd=open("/etc/inittab", O_CREAT | O_RDWR ,S_IRWXU);
    rcS_fd=open("/etc/init.d/rcS", O_CREAT | O_RDWR ,S_IRWXU);
    passwd_fd=open("/etc/passwd", O_CREAT | O_RDWR ,S_IRWXU);
    group_fd=open("/etc/group", O_CREAT | O_RDWR ,S_IRWXU);

    if(!inittab_fd)
    {
        printk("### cannot open /etc/inittab\n");
    }
    else
    {
        write(inittab_fd,"::sysinit:/etc/init.d/rcS\nttyS0::respawn:-/sbin/getty -L ttyS0 9600 vt100\n",
                strlen("::sysinit:/etc/init.d/rcS\nttyS0::respawn:-/sbin/getty -L ttyS0 9600 vt100\n"));
        close(inittab_fd);
    }

    if(!rcS_fd)
    {
        printk("### cannot open /etc/init.d/rcS\n");
    }
    else
    {
        write(rcS_fd,"#! /bin/sh\nPATH=/bin:/sbin\n",strlen("#! /bin/sh\nPATH=/bin:/sbin\n"));
        close(rcS_fd);
    }
    if(!passwd_fd)
    {
        printk("### cannot open /etc/passwd\n");
    }
    else
    {
        write(passwd_fd,"root:.GNRdJai/a8pc:0:0::/root:/bin/sh\n",
                strlen("root:.GNRdJai/a8pc:0:0::/root:/bin/sh\n"));
        close(passwd_fd);
    }
   
    if(!group_fd)
    {
        printk("### cannot open /etc/group\n");
    }
    else
    {
        write(group_fd,"root:x:0:root\n",strlen("root:x:0:root\n"));
        close(group_fd);
    }

    i=0;
    while(busybox_cmd[i] != NULL)
    {
        busybox_fd=open(busybox_cmd[i], O_CREAT | O_RDWR ,S_IRWXU);
        if(!busybox_fd)
        {
          printk("### cannot create %s\n",busybox_cmd[i]);
        }
        else
        {
          ret=write(busybox_fd,busybox_data,sizeof(busybox_data));
          close(busybox_fd);
          printk("### create %s successfully\n",busybox_cmd[i]);
        }
        i++;
    }
}


我用这段代码来代替mount_root(),根文件系统能成功创建,init进程也起来了,但init执行getty时,getty老是执行不了/bin/login,说/bin/login不存在,我明明已经创建了这个程序.

本来我是想建立一个/bin/busybox,然后其他程序做个链接就行了,但我用sys_smblink却不能成功创建链接,不得已,我只好为每个busybox支持的命令都创建一个实体.

mozilla 发表于 2004-12-10 15:56:52

另外用initrd的话,我不知道在内核里怎么去load他,因为我没有lilo,grub之类的引导器.

suowei1979 发表于 2004-12-10 16:17:34

没用 bootloader?

mozilla 发表于 2004-12-10 17:15:41

bootloader就是bios,内核是放在ROM的固定位置,bios负责把它load进来
页: [1]
查看完整版本: 在内核了想往ramdisk里写点东西,但不让写.