Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
a06650df
Commit
a06650df
authored
Nov 01, 2002
by
Jeff Garzik
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Minimal initramfs support (based on Al Viro's work).
parent
2b738648
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
627 additions
and
5 deletions
+627
-5
Makefile
Makefile
+1
-1
arch/i386/Makefile
arch/i386/Makefile
+1
-0
arch/i386/vmlinux.lds.S
arch/i386/vmlinux.lds.S
+4
-0
init/Makefile
init/Makefile
+1
-1
init/do_mounts.c
init/do_mounts.c
+1
-3
init/initramfs.c
init/initramfs.c
+462
-0
init/main.c
init/main.c
+2
-0
usr/Makefile
usr/Makefile
+18
-0
usr/gen_init_cpio.c
usr/gen_init_cpio.c
+137
-0
No files found.
Makefile
View file @
a06650df
...
...
@@ -209,7 +209,7 @@ init-y := init/
drivers-y
:=
drivers/ sound/
net-y
:=
net/
libs-y
:=
lib/
core-y
:=
core-y
:=
usr/
SUBDIRS
:=
ifeq
($(filter $(noconfig_targets),$(MAKECMDGOALS)),)
...
...
arch/i386/Makefile
View file @
a06650df
...
...
@@ -18,6 +18,7 @@
LDFLAGS
:=
-m
elf_i386
OBJCOPYFLAGS
:=
-O
binary
-R
.note
-R
.comment
-S
ARCHBLOBLFLAGS
:=
-I
binary
-O
elf32-i386
-B
i386
LDFLAGS_vmlinux
:=
-e
stext
CFLAGS
+=
-pipe
...
...
arch/i386/vmlinux.lds.S
View file @
a06650df
...
...
@@ -77,6 +77,10 @@ SECTIONS
*(.
initcall7.init
)
}
__initcall_end
=
.
;
.
=
ALIGN
(
4096
)
;
__initramfs_start
=
.
;
.
init.ramfs
:
{
*(
.
init
.
initramfs
)
}
__initramfs_end
=
.
;
.
=
ALIGN
(
32
)
;
__per_cpu_start
=
.
;
.
data.percpu
:
{
*(
.
data
.
percpu
)
}
...
...
init/Makefile
View file @
a06650df
...
...
@@ -2,7 +2,7 @@
# Makefile for the linux kernel.
#
obj-y
:=
main.o version.o do_mounts.o
obj-y
:=
main.o version.o do_mounts.o
initramfs.o
# files to be removed upon make clean
clean-files
:=
../include/linux/compile.h
...
...
init/do_mounts.c
View file @
a06650df
...
...
@@ -748,9 +748,7 @@ void prepare_namespace(void)
mount_initrd
=
0
;
real_root_dev
=
ROOT_DEV
;
#endif
sys_mkdir
(
"/dev"
,
0700
);
sys_mkdir
(
"/root"
,
0700
);
sys_mknod
(
"/dev/console"
,
S_IFCHR
|
0600
,
MKDEV
(
TTYAUX_MAJOR
,
1
));
#ifdef CONFIG_DEVFS_FS
sys_mount
(
"devfs"
,
"/dev"
,
"devfs"
,
0
,
NULL
);
do_devfs
=
1
;
...
...
init/initramfs.c
0 → 100644
View file @
a06650df
#define __KERNEL_SYSCALLS__
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/fcntl.h>
#include <linux/unistd.h>
#include <linux/delay.h>
static
void
__init
error
(
char
*
x
)
{
panic
(
"populate_root: %s
\n
"
,
x
);
}
static
void
__init
*
malloc
(
int
size
)
{
return
kmalloc
(
size
,
GFP_KERNEL
);
}
static
void
__init
free
(
void
*
where
)
{
kfree
(
where
);
}
asmlinkage
long
sys_mkdir
(
char
*
name
,
int
mode
);
asmlinkage
long
sys_mknod
(
char
*
name
,
int
mode
,
dev_t
dev
);
asmlinkage
long
sys_symlink
(
char
*
old
,
char
*
new
);
asmlinkage
long
sys_link
(
char
*
old
,
char
*
new
);
asmlinkage
long
sys_write
(
int
fd
,
void
*
buf
,
ssize_t
size
);
asmlinkage
long
sys_chown
(
char
*
name
,
uid_t
uid
,
gid_t
gid
);
asmlinkage
long
sys_lchown
(
char
*
name
,
uid_t
uid
,
gid_t
gid
);
asmlinkage
long
sys_fchown
(
int
fd
,
uid_t
uid
,
gid_t
gid
);
asmlinkage
long
sys_chmod
(
char
*
name
,
mode_t
mode
);
asmlinkage
long
sys_fchmod
(
int
fd
,
mode_t
mode
);
/* link hash */
static
struct
hash
{
int
ino
,
minor
,
major
;
struct
hash
*
next
;
char
*
name
;
}
*
head
[
32
];
static
inline
int
hash
(
int
major
,
int
minor
,
int
ino
)
{
unsigned
long
tmp
=
ino
+
minor
+
(
major
<<
3
);
tmp
+=
tmp
>>
5
;
return
tmp
&
31
;
}
static
char
__init
*
find_link
(
int
major
,
int
minor
,
int
ino
,
char
*
name
)
{
struct
hash
**
p
,
*
q
;
for
(
p
=
head
+
hash
(
major
,
minor
,
ino
);
*
p
;
p
=
&
(
*
p
)
->
next
)
{
if
((
*
p
)
->
ino
!=
ino
)
continue
;
if
((
*
p
)
->
minor
!=
minor
)
continue
;
if
((
*
p
)
->
major
!=
major
)
continue
;
return
(
*
p
)
->
name
;
}
q
=
(
struct
hash
*
)
malloc
(
sizeof
(
struct
hash
));
if
(
!
q
)
error
(
"can't allocate link hash entry"
);
q
->
ino
=
ino
;
q
->
minor
=
minor
;
q
->
major
=
major
;
q
->
name
=
name
;
q
->
next
=
NULL
;
*
p
=
q
;
return
NULL
;
}
static
void
__init
free_hash
(
void
)
{
struct
hash
**
p
,
*
q
;
for
(
p
=
head
;
p
<
head
+
32
;
p
++
)
{
while
(
*
p
)
{
q
=
*
p
;
*
p
=
q
->
next
;
free
(
q
);
}
}
}
/* cpio header parsing */
static
__initdata
unsigned
long
ino
,
major
,
minor
,
nlink
;
static
__initdata
mode_t
mode
;
static
__initdata
unsigned
long
body_len
,
name_len
;
static
__initdata
uid_t
uid
;
static
__initdata
gid_t
gid
;
static
__initdata
dev_t
rdev
;
static
void
__init
parse_header
(
char
*
s
)
{
unsigned
long
parsed
[
12
];
char
buf
[
9
];
int
i
;
buf
[
8
]
=
'\0'
;
for
(
i
=
0
,
s
+=
6
;
i
<
12
;
i
++
,
s
+=
8
)
{
memcpy
(
buf
,
s
,
8
);
parsed
[
i
]
=
simple_strtoul
(
buf
,
NULL
,
16
);
}
ino
=
parsed
[
0
];
mode
=
parsed
[
1
];
uid
=
parsed
[
2
];
gid
=
parsed
[
3
];
nlink
=
parsed
[
4
];
body_len
=
parsed
[
6
];
major
=
parsed
[
7
];
minor
=
parsed
[
8
];
rdev
=
MKDEV
(
parsed
[
9
],
parsed
[
10
]);
name_len
=
parsed
[
11
];
}
/* FSM */
enum
state
{
Start
,
Collect
,
GotHeader
,
SkipIt
,
GotName
,
CopyFile
,
GotSymlink
,
Reset
}
state
,
next_state
;
char
*
victim
;
unsigned
count
;
loff_t
this_header
,
next_header
;
static
inline
void
eat
(
unsigned
n
)
{
victim
+=
n
;
this_header
+=
n
;
count
-=
n
;
}
#define N_ALIGN(len) ((((len) + 1) & ~3) + 2)
static
__initdata
char
*
collected
;
static
__initdata
int
remains
;
static
__initdata
char
*
collect
;
static
void
__init
read_into
(
char
*
buf
,
unsigned
size
,
enum
state
next
)
{
if
(
count
>=
size
)
{
collected
=
victim
;
eat
(
size
);
state
=
next
;
}
else
{
collect
=
collected
=
buf
;
remains
=
size
;
next_state
=
next
;
state
=
Collect
;
}
}
static
__initdata
char
*
header_buf
,
*
symlink_buf
,
*
name_buf
;
static
int
__init
do_start
(
void
)
{
read_into
(
header_buf
,
110
,
GotHeader
);
return
0
;
}
static
int
__init
do_collect
(
void
)
{
unsigned
n
=
remains
;
if
(
count
<
n
)
n
=
count
;
memcpy
(
collect
,
victim
,
n
);
eat
(
n
);
collect
+=
n
;
if
(
remains
-=
n
)
return
1
;
state
=
next_state
;
return
0
;
}
static
int
__init
do_header
(
void
)
{
parse_header
(
collected
);
next_header
=
this_header
+
N_ALIGN
(
name_len
)
+
body_len
;
next_header
=
(
next_header
+
3
)
&
~
3
;
if
(
name_len
<=
0
||
name_len
>
PATH_MAX
)
state
=
SkipIt
;
else
if
(
S_ISLNK
(
mode
))
{
if
(
body_len
>
PATH_MAX
)
state
=
SkipIt
;
else
{
collect
=
collected
=
symlink_buf
;
remains
=
N_ALIGN
(
name_len
)
+
body_len
;
next_state
=
GotSymlink
;
state
=
Collect
;
}
}
else
if
(
body_len
&&
!
S_ISREG
(
mode
))
state
=
SkipIt
;
else
read_into
(
name_buf
,
N_ALIGN
(
name_len
),
GotName
);
return
0
;
}
static
int
__init
do_skip
(
void
)
{
if
(
this_header
+
count
<=
next_header
)
{
eat
(
count
);
return
1
;
}
else
{
eat
(
next_header
-
this_header
);
state
=
next_state
;
return
0
;
}
}
static
int
__init
do_reset
(
void
)
{
while
(
count
&&
*
victim
==
'\0'
)
eat
(
1
);
if
(
count
&&
(
this_header
&
3
))
error
(
"broken padding"
);
return
1
;
}
static
int
__init
maybe_link
(
void
)
{
if
(
nlink
>=
2
)
{
char
*
old
=
find_link
(
major
,
minor
,
ino
,
collected
);
if
(
old
)
return
(
sys_link
(
old
,
collected
)
<
0
)
?
-
1
:
1
;
}
return
0
;
}
static
__initdata
int
wfd
;
static
int
__init
do_name
(
void
)
{
state
=
SkipIt
;
next_state
=
Start
;
if
(
strcmp
(
collected
,
"TRAILER!!!"
)
==
0
)
{
free_hash
();
next_state
=
Reset
;
return
0
;
}
printk
(
KERN_INFO
"-> %s
\n
"
,
collected
);
if
(
S_ISREG
(
mode
))
{
if
(
maybe_link
()
>=
0
)
{
wfd
=
sys_open
(
collected
,
O_WRONLY
|
O_CREAT
,
mode
);
if
(
wfd
>=
0
)
{
sys_fchown
(
wfd
,
uid
,
gid
);
sys_fchmod
(
wfd
,
mode
);
state
=
CopyFile
;
}
}
}
else
if
(
S_ISDIR
(
mode
))
{
sys_mkdir
(
collected
,
mode
);
sys_chown
(
collected
,
uid
,
gid
);
}
else
if
(
S_ISBLK
(
mode
)
||
S_ISCHR
(
mode
)
||
S_ISFIFO
(
mode
)
||
S_ISSOCK
(
mode
))
{
if
(
maybe_link
()
==
0
)
{
sys_mknod
(
collected
,
mode
,
rdev
);
sys_chown
(
collected
,
uid
,
gid
);
}
}
else
panic
(
"populate_root: bogus mode: %o
\n
"
,
mode
);
return
0
;
}
static
int
__init
do_copy
(
void
)
{
if
(
count
>=
body_len
)
{
sys_write
(
wfd
,
victim
,
body_len
);
sys_close
(
wfd
);
eat
(
body_len
);
state
=
SkipIt
;
return
0
;
}
else
{
sys_write
(
wfd
,
victim
,
count
);
body_len
-=
count
;
eat
(
count
);
return
1
;
}
}
static
int
__init
do_symlink
(
void
)
{
collected
[
N_ALIGN
(
name_len
)
+
body_len
]
=
'\0'
;
sys_symlink
(
collected
+
N_ALIGN
(
name_len
),
collected
);
sys_lchown
(
collected
,
uid
,
gid
);
state
=
SkipIt
;
next_state
=
Start
;
return
0
;
}
static
__initdata
int
(
*
actions
[])(
void
)
=
{
[
Start
]
do_start
,
[
Collect
]
do_collect
,
[
GotHeader
]
do_header
,
[
SkipIt
]
do_skip
,
[
GotName
]
do_name
,
[
CopyFile
]
do_copy
,
[
GotSymlink
]
do_symlink
,
[
Reset
]
do_reset
,
};
static
int
__init
write_buffer
(
char
*
buf
,
unsigned
len
)
{
count
=
len
;
victim
=
buf
;
while
(
!
actions
[
state
]())
;
return
len
-
count
;
}
static
void
__init
flush_buffer
(
char
*
buf
,
unsigned
len
)
{
int
written
;
while
((
written
=
write_buffer
(
buf
,
len
))
<
len
)
{
char
c
=
buf
[
written
];
if
(
c
==
'0'
)
{
buf
+=
written
;
len
-=
written
;
state
=
Start
;
continue
;
}
else
error
(
"junk in compressed archive"
);
}
}
/*
* gzip declarations
*/
#define OF(args) args
#ifndef memzero
#define memzero(s, n) memset ((s), 0, (n))
#endif
typedef
unsigned
char
uch
;
typedef
unsigned
short
ush
;
typedef
unsigned
long
ulg
;
#define WSIZE 0x8000
/* window size--must be a power of two, and */
/* at least 32K for zip's deflate method */
static
uch
*
inbuf
;
static
uch
*
window
;
static
unsigned
insize
;
/* valid bytes in inbuf */
static
unsigned
inptr
;
/* index of next byte to be processed in inbuf */
static
unsigned
outcnt
;
/* bytes in output buffer */
static
long
bytes_out
;
#define get_byte() (inptr < insize ? inbuf[inptr++] : -1)
/* Diagnostic functions (stubbed out) */
#define Assert(cond,msg)
#define Trace(x)
#define Tracev(x)
#define Tracevv(x)
#define Tracec(c,x)
#define Tracecv(c,x)
#define STATIC static
static
void
flush_window
(
void
);
static
void
error
(
char
*
m
);
static
void
gzip_mark
(
void
**
);
static
void
gzip_release
(
void
**
);
#include "../lib/inflate.c"
static
void
__init
gzip_mark
(
void
**
ptr
)
{
}
static
void
__init
gzip_release
(
void
**
ptr
)
{
}
/* ===========================================================================
* Write the output window window[0..outcnt-1] and update crc and bytes_out.
* (Used for the decompressed data only.)
*/
static
void
__init
flush_window
(
void
)
{
ulg
c
=
crc
;
/* temporary variable */
unsigned
n
;
uch
*
in
,
ch
;
flush_buffer
(
window
,
outcnt
);
in
=
window
;
for
(
n
=
0
;
n
<
outcnt
;
n
++
)
{
ch
=
*
in
++
;
c
=
crc_32_tab
[((
int
)
c
^
ch
)
&
0xff
]
^
(
c
>>
8
);
}
crc
=
c
;
bytes_out
+=
(
ulg
)
outcnt
;
outcnt
=
0
;
}
static
void
__init
unpack_to_rootfs
(
char
*
buf
,
unsigned
len
)
{
int
written
;
header_buf
=
malloc
(
110
);
symlink_buf
=
malloc
(
PATH_MAX
+
N_ALIGN
(
PATH_MAX
)
+
1
);
name_buf
=
malloc
(
N_ALIGN
(
PATH_MAX
));
window
=
malloc
(
WSIZE
);
if
(
!
window
||
!
header_buf
||
!
symlink_buf
||
!
name_buf
)
error
(
"can't allocate buffers"
);
state
=
Start
;
this_header
=
0
;
while
(
len
)
{
loff_t
saved_offset
=
this_header
;
if
(
*
buf
==
'0'
&&
!
(
this_header
&
3
))
{
state
=
Start
;
written
=
write_buffer
(
buf
,
len
);
buf
+=
written
;
len
-=
written
;
continue
;
}
else
if
(
!*
buf
)
{
buf
++
;
len
--
;
this_header
++
;
continue
;
}
this_header
=
0
;
insize
=
len
;
inbuf
=
buf
;
inptr
=
0
;
outcnt
=
0
;
/* bytes in output buffer */
bytes_out
=
0
;
crc
=
(
ulg
)
0xffffffffL
;
/* shift register contents */
makecrc
();
if
(
gunzip
())
error
(
"ungzip failed"
);
if
(
state
!=
Reset
)
error
(
"junk in gzipped archive"
);
this_header
=
saved_offset
+
inptr
;
buf
+=
inptr
;
len
-=
inptr
;
}
free
(
window
);
free
(
name_buf
);
free
(
symlink_buf
);
free
(
header_buf
);
}
extern
unsigned
long
__initramfs_start
,
__initramfs_end
;
void
__init
populate_rootfs
(
void
)
{
unpack_to_rootfs
((
void
*
)
&
__initramfs_start
,
&
__initramfs_end
-
&
__initramfs_start
);
}
init/main.c
View file @
a06650df
...
...
@@ -72,6 +72,7 @@ extern void pidhash_init(void);
extern
void
pte_chain_init
(
void
);
extern
void
radix_tree_init
(
void
);
extern
void
free_initmem
(
void
);
extern
void
populate_rootfs
(
void
);
#ifdef CONFIG_TC
extern
void
tc_init
(
void
);
...
...
@@ -433,6 +434,7 @@ asmlinkage void __init start_kernel(void)
vfs_caches_init
(
num_physpages
);
radix_tree_init
();
signals_init
();
populate_rootfs
();
#ifdef CONFIG_PROC_FS
proc_root_init
();
#endif
...
...
usr/Makefile
0 → 100644
View file @
a06650df
include
arch/$(ARCH)/Makefile
obj-y
:=
initramfs_data.o
host-progs
:=
gen_init_cpio
clean-files
:=
initramfs_data.cpio.gz
$(obj)/initramfs_data.o
:
$(obj)/initramfs_data.cpio.gz
$(OBJCOPY)
$(ARCHBLOBLFLAGS)
\
--rename-section
.data
=
.init.initramfs
\
$(obj)
/initramfs_data.cpio.gz
$(obj)
/initramfs_data.o
$(STRIP)
-s
$(obj)
/initramfs_data.o
$(obj)/initramfs_data.cpio.gz
:
$(obj)/gen_init_cpio
(
cd
$(obj)
;
./gen_init_cpio |
gzip
-9c
>
initramfs_data.cpio.gz
)
usr/gen_init_cpio.c
0 → 100644
View file @
a06650df
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
static
unsigned
int
offset
;
static
unsigned
int
ino
=
721
;
static
void
push_rest
(
const
char
*
name
)
{
unsigned
int
name_len
=
strlen
(
name
)
+
1
;
unsigned
int
tmp_ofs
;
fputs
(
name
,
stdout
);
putchar
(
0
);
offset
+=
name_len
;
tmp_ofs
=
name_len
+
110
;
while
(
tmp_ofs
&
3
)
{
putchar
(
0
);
offset
++
;
tmp_ofs
++
;
}
}
static
void
push_hdr
(
const
char
*
s
)
{
fputs
(
s
,
stdout
);
offset
+=
110
;
}
static
void
cpio_trailer
(
void
)
{
char
s
[
256
];
const
char
*
name
=
"TRAILER!!!"
;
sprintf
(
s
,
"%s%08X%08X%08lX%08lX%08X%08lX"
"%08X%08X%08X%08X%08X%08X%08X"
,
"070701"
,
/* magic */
0
,
/* ino */
0
,
/* mode */
(
long
)
0
,
/* uid */
(
long
)
0
,
/* gid */
1
,
/* nlink */
(
long
)
0
,
/* mtime */
0
,
/* filesize */
0
,
/* major */
0
,
/* minor */
0
,
/* rmajor */
0
,
/* rminor */
strlen
(
name
)
+
1
,
/* namesize */
0
);
/* chksum */
push_hdr
(
s
);
push_rest
(
name
);
while
(
offset
%
512
)
{
putchar
(
0
);
offset
++
;
}
}
static
void
cpio_mkdir
(
const
char
*
name
,
unsigned
int
mode
,
uid_t
uid
,
gid_t
gid
)
{
char
s
[
256
];
time_t
mtime
=
time
(
NULL
);
sprintf
(
s
,
"%s%08X%08X%08lX%08lX%08X%08lX"
"%08X%08X%08X%08X%08X%08X%08X"
,
"070701"
,
/* magic */
ino
++
,
/* ino */
S_IFDIR
|
mode
,
/* mode */
(
long
)
uid
,
/* uid */
(
long
)
gid
,
/* gid */
2
,
/* nlink */
(
long
)
mtime
,
/* mtime */
0
,
/* filesize */
3
,
/* major */
1
,
/* minor */
0
,
/* rmajor */
0
,
/* rminor */
strlen
(
name
)
+
1
,
/* namesize */
0
);
/* chksum */
push_hdr
(
s
);
push_rest
(
name
);
}
static
void
cpio_mknod
(
const
char
*
name
,
unsigned
int
mode
,
uid_t
uid
,
gid_t
gid
,
int
dev_type
,
unsigned
int
maj
,
unsigned
int
min
)
{
char
s
[
256
];
time_t
mtime
=
time
(
NULL
);
if
(
dev_type
==
'b'
)
mode
|=
S_IFBLK
;
else
mode
|=
S_IFCHR
;
sprintf
(
s
,
"%s%08X%08X%08lX%08lX%08X%08lX"
"%08X%08X%08X%08X%08X%08X%08X"
,
"070701"
,
/* magic */
ino
++
,
/* ino */
mode
,
/* mode */
(
long
)
uid
,
/* uid */
(
long
)
gid
,
/* gid */
1
,
/* nlink */
(
long
)
mtime
,
/* mtime */
0
,
/* filesize */
3
,
/* major */
1
,
/* minor */
maj
,
/* rmajor */
min
,
/* rminor */
strlen
(
name
)
+
1
,
/* namesize */
0
);
/* chksum */
push_hdr
(
s
);
push_rest
(
name
);
}
int
main
(
int
argc
,
char
*
argv
[])
{
cpio_mkdir
(
"/dev"
,
0700
,
0
,
0
);
cpio_mknod
(
"/dev/console"
,
0600
,
0
,
0
,
'c'
,
5
,
1
);
cpio_mkdir
(
"/root"
,
0700
,
0
,
0
);
cpio_trailer
();
exit
(
0
);
/* silence compiler warnings */
return
0
;
(
void
)
argc
;
(
void
)
argv
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment