在内核了想往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是否表示设备文件已经成功生成? 是读写权限问题? 内核中操作文件不能用普通程序那样的/dev/ram的形式。那个形式的意思是根已经mount了,才能顺着根找dev目录,再找ram文件。
内核中必须直接用inode来操作文件,另外,把那个设备mount成根可以通过内核的启动参数来指定。
我认为不可能改内核的某个文件来mount根,因为你不能确定所有的设备是否已经初始化完了,也就是那个设备是否可以使用。
我想好好参考一下initrd的使用也许会有帮助。
参看一下模块是如何访问设备文件的,由于模块是在内核启动完后装载入内核的,所以尽管它是内核的一部分,但可以认为所有的内核资源都已经可以使用。
http://www.tldp.org/LDP/lkmpg/2.4/html/x856.html
呵呵,强调一句,偶是纸上谈兵,必须要请教有实际经验的高手才是万全之策。 我改变了一下根文件系统的创建方式,不直接去写/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支持的命令都创建一个实体. 另外用initrd的话,我不知道在内核里怎么去load他,因为我没有lilo,grub之类的引导器. 没用 bootloader? bootloader就是bios,内核是放在ROM的固定位置,bios负责把它load进来
页:
[1]