0.1 from Bellard
This commit is contained in:
parent
fa20438104
commit
cbf2807505
|
@ -0,0 +1,45 @@
|
||||||
|
# modify to your linux-2.4.26 kernel path (you must build the kernel first)
|
||||||
|
KERNEL_PATH=../linux-2.4.26
|
||||||
|
# modify to your TinyCC 0.9.21 path (you must build TinyCC first)
|
||||||
|
TCC_PATH=../..
|
||||||
|
CC=gcc
|
||||||
|
CFLAGS=-D__KERNEL__ -Wall -O2 -g -I$(KERNEL_PATH)/include -fno-builtin-printf -DCONFIG_TCCBOOT -mpreferred-stack-boundary=2 -march=i386 -falign-functions=0 -I.
|
||||||
|
|
||||||
|
all: tccboot initrd.img
|
||||||
|
|
||||||
|
#tccboot.user: tcc.o main.o ctype.o vsprintf.o lib.o malloc.o dtoa.o user.o
|
||||||
|
# $(CC) -static -nostdlib -o $@ $^
|
||||||
|
|
||||||
|
tccboot.out: head.o tcc.o main.o ctype.o vsprintf.o lib.o malloc.o \
|
||||||
|
dtoa.o gunzip.o
|
||||||
|
ld -e startup_32 -Ttext=0x100000 -N -o $@ $^
|
||||||
|
|
||||||
|
tccboot.bin: tccboot.out
|
||||||
|
objcopy -O binary -R .note -R .comment -S $< $@
|
||||||
|
|
||||||
|
tccboot: tccboot.bin
|
||||||
|
$(KERNEL_PATH)/arch/i386/boot/tools/build \
|
||||||
|
-b $(KERNEL_PATH)/arch/i386/boot/bbootsect \
|
||||||
|
$(KERNEL_PATH)/arch/i386/boot/bsetup \
|
||||||
|
$< CURRENT > $@
|
||||||
|
|
||||||
|
tcc.o: $(TCC_PATH)/tcc.c
|
||||||
|
$(CC) $(CFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
|
%.o: %.c
|
||||||
|
$(CC) $(CFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
|
%.o: %.S
|
||||||
|
$(CC) -D__ASSEMBLY__ -D__KERNEL__ -I$(KERNEL_PATH)/include -c -o $@ $<
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f *~ *.o tccboot.out tccboot.bin example.romfs
|
||||||
|
|
||||||
|
cleanall: clean
|
||||||
|
rm -f tccboot example.romfs initrd.img
|
||||||
|
|
||||||
|
example.romfs: example/boot/tccargs example/hello.c
|
||||||
|
cd example ; genromfs -f ../example.romfs
|
||||||
|
|
||||||
|
initrd.img: example.romfs
|
||||||
|
gzip < $< > $@
|
|
@ -0,0 +1,64 @@
|
||||||
|
Introduction:
|
||||||
|
------------
|
||||||
|
|
||||||
|
WARNING: don't try to play with TCCBOOT unless you are a kernel
|
||||||
|
hacker!
|
||||||
|
|
||||||
|
TCCBOOT is a bootloader which uses TinyCC to compile C and assembly
|
||||||
|
sources and boot the resulting executable. It is typically used to
|
||||||
|
compile the Linux kernel sources at boot time.
|
||||||
|
|
||||||
|
TCCBOOT boots the same way as a Linux kernel, so any boot loader which
|
||||||
|
can run a 'bzImage' Linux kernel image can run TCCBOOT. I only tested
|
||||||
|
it with ISOLINUX, but LILO or GRUB should work too.
|
||||||
|
|
||||||
|
TCCBOOT reads C or assembly sources from a gzipped ROMFS filesystem
|
||||||
|
stored in an Initial Ram Disk (initrd). It first reads the file
|
||||||
|
'boot/tccargs' which contains the TinyCC command line (same syntax as
|
||||||
|
the tcc executable). The TinyCC invocation should output one binary
|
||||||
|
image 'kernel'. This image is loaded at address 0x00100000. TCCBOOT
|
||||||
|
then does a jump to the address 0x00100000 in 32 bit flat mode. This
|
||||||
|
is compatible with the ABI of the 'vmlinux' kernel image.
|
||||||
|
|
||||||
|
Compilation:
|
||||||
|
-----------
|
||||||
|
|
||||||
|
TCCBOOT was only tested with Linux 2.4.26. In order to build TCCBOOT,
|
||||||
|
you must first compile a 2.4.26 kernel because for simplicity TCCBOOT
|
||||||
|
uses some binary files and headers from the Linux kernel. TCCBOOT also
|
||||||
|
needs the source code of TinyCC (tested with TinyCC version
|
||||||
|
0.9.21). You can modify the Makefile to give the needed paths.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
-------
|
||||||
|
|
||||||
|
An "Hello World" ROMFS partition is included (initrd.img). You can
|
||||||
|
rebuild it from the example/ directory. You can test it with the QEMU
|
||||||
|
PC emulator with the 'qemu-tccboot' script.
|
||||||
|
|
||||||
|
Kernel compilation:
|
||||||
|
------------------
|
||||||
|
|
||||||
|
For your information, the patch 'linux-2.4.26-tcc.patch' gives the
|
||||||
|
necessary modifications to build a Linux kernel with TinyCC. The
|
||||||
|
corresponding kernel configuration is in file
|
||||||
|
linux-2.4.26-config. Patches are necessary for the following reasons:
|
||||||
|
|
||||||
|
- unsupported assembly directives: .rept, .endr, .subsection
|
||||||
|
- '#define __ASSEMBLY__' needed in assembly sources
|
||||||
|
- static variables cannot be seen from the inline assembly code
|
||||||
|
- typing/lvalue problems with '? :'
|
||||||
|
- no long long bit fields
|
||||||
|
- 'aligned' attribute not supported for whole structs, only for fields
|
||||||
|
- obscur preprocessor bug
|
||||||
|
|
||||||
|
Some of these problems could easily be fixed, but I am too lazy
|
||||||
|
now. It is sure that there are still many bugs in the kernel generated
|
||||||
|
by TinyCC/TCCBOOT, but at least it can boot and launch a shell.
|
||||||
|
|
||||||
|
License:
|
||||||
|
-------
|
||||||
|
|
||||||
|
TCCBOOT is distributed under the GNU General Public License.
|
||||||
|
|
||||||
|
Fabrice Bellard.
|
|
@ -0,0 +1,35 @@
|
||||||
|
/*
|
||||||
|
* linux/lib/ctype.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 1991, 1992 Linus Torvalds
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/ctype.h>
|
||||||
|
|
||||||
|
unsigned char _ctype[] = {
|
||||||
|
_C,_C,_C,_C,_C,_C,_C,_C, /* 0-7 */
|
||||||
|
_C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C, /* 8-15 */
|
||||||
|
_C,_C,_C,_C,_C,_C,_C,_C, /* 16-23 */
|
||||||
|
_C,_C,_C,_C,_C,_C,_C,_C, /* 24-31 */
|
||||||
|
_S|_SP,_P,_P,_P,_P,_P,_P,_P, /* 32-39 */
|
||||||
|
_P,_P,_P,_P,_P,_P,_P,_P, /* 40-47 */
|
||||||
|
_D,_D,_D,_D,_D,_D,_D,_D, /* 48-55 */
|
||||||
|
_D,_D,_P,_P,_P,_P,_P,_P, /* 56-63 */
|
||||||
|
_P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U, /* 64-71 */
|
||||||
|
_U,_U,_U,_U,_U,_U,_U,_U, /* 72-79 */
|
||||||
|
_U,_U,_U,_U,_U,_U,_U,_U, /* 80-87 */
|
||||||
|
_U,_U,_U,_P,_P,_P,_P,_P, /* 88-95 */
|
||||||
|
_P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L, /* 96-103 */
|
||||||
|
_L,_L,_L,_L,_L,_L,_L,_L, /* 104-111 */
|
||||||
|
_L,_L,_L,_L,_L,_L,_L,_L, /* 112-119 */
|
||||||
|
_L,_L,_L,_P,_P,_P,_P,_C, /* 120-127 */
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 128-143 */
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 144-159 */
|
||||||
|
_S|_SP,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 160-175 */
|
||||||
|
_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 176-191 */
|
||||||
|
_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U, /* 192-207 */
|
||||||
|
_U,_U,_U,_U,_U,_U,_U,_P,_U,_U,_U,_U,_U,_U,_U,_L, /* 208-223 */
|
||||||
|
_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L, /* 224-239 */
|
||||||
|
_L,_L,_L,_L,_L,_L,_L,_P,_L,_L,_L,_L,_L,_L,_L,_L}; /* 240-255 */
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
# This file contains the TinyCC command line arguments needed to
|
||||||
|
# compile the hello.c program.
|
||||||
|
|
||||||
|
# the output binary (DO NOT CHANGE IT)
|
||||||
|
-o kernel
|
||||||
|
# no default libraries
|
||||||
|
-nostdlib
|
||||||
|
# no default includes paths
|
||||||
|
-nostdinc
|
||||||
|
# statically linked output
|
||||||
|
-static
|
||||||
|
# address of the start of the .text section
|
||||||
|
-Wl,-Ttext,000100000
|
||||||
|
# force binary output format
|
||||||
|
-Wl,--oformat,binary
|
||||||
|
# sources files
|
||||||
|
hello.c
|
|
@ -0,0 +1,32 @@
|
||||||
|
/* simple Hello World program on the QEMU serial port */
|
||||||
|
|
||||||
|
void puts(const char *s);
|
||||||
|
|
||||||
|
void _start(void)
|
||||||
|
{
|
||||||
|
puts("Hello World\n");
|
||||||
|
while (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void outb(int port, int val)
|
||||||
|
{
|
||||||
|
asm("outb %b1, %w0" : : "d" (port), "a" (val));
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char inb(int port)
|
||||||
|
{
|
||||||
|
int val;
|
||||||
|
asm("inb %w1, %b0" : "=a"(val) : "d" (port));
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
void puts(const char *s)
|
||||||
|
{
|
||||||
|
while (*s) {
|
||||||
|
outb(0x3f8, *s++);
|
||||||
|
while ((inb(0x3f8 + 5) & 0x60) != 0x60);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,109 @@
|
||||||
|
#include "tccboot.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* gzip declarations
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define OF(args) args
|
||||||
|
#define STATIC static
|
||||||
|
|
||||||
|
#define memzero(s, n) memset ((s), 0, (n))
|
||||||
|
|
||||||
|
typedef unsigned char uch;
|
||||||
|
typedef unsigned short ush;
|
||||||
|
typedef unsigned long ulg;
|
||||||
|
|
||||||
|
#define WSIZE 0x8000 /* Window size must be at least 32k, */
|
||||||
|
/* and a power of two */
|
||||||
|
|
||||||
|
static uch *inbuf; /* input buffer */
|
||||||
|
static uch window[WSIZE]; /* Sliding window buffer */
|
||||||
|
|
||||||
|
static unsigned insize = 0; /* valid bytes in inbuf */
|
||||||
|
static unsigned inptr = 0; /* index of next byte to be processed in inbuf */
|
||||||
|
static unsigned outcnt = 0; /* bytes in output buffer */
|
||||||
|
|
||||||
|
/* gzip flag byte */
|
||||||
|
#define ASCII_FLAG 0x01 /* bit 0 set: file probably ASCII text */
|
||||||
|
#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */
|
||||||
|
#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
|
||||||
|
#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
|
||||||
|
#define COMMENT 0x10 /* bit 4 set: file comment present */
|
||||||
|
#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */
|
||||||
|
#define RESERVED 0xC0 /* bit 6,7: reserved */
|
||||||
|
|
||||||
|
#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf())
|
||||||
|
|
||||||
|
/* Diagnostic functions */
|
||||||
|
#ifdef DEBUG
|
||||||
|
# define Assert(cond,msg) {if(!(cond)) error(msg);}
|
||||||
|
# define Trace(x) fprintf x
|
||||||
|
# define Tracev(x) {if (verbose) fprintf x ;}
|
||||||
|
# define Tracevv(x) {if (verbose>1) fprintf x ;}
|
||||||
|
# define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
|
||||||
|
# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
|
||||||
|
#else
|
||||||
|
# define Assert(cond,msg)
|
||||||
|
# define Trace(x)
|
||||||
|
# define Tracev(x)
|
||||||
|
# define Tracevv(x)
|
||||||
|
# define Tracec(c,x)
|
||||||
|
# define Tracecv(c,x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int fill_inbuf(void);
|
||||||
|
static void flush_window(void);
|
||||||
|
static void error(char *m);
|
||||||
|
|
||||||
|
static void gzip_mark(void **ptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
static void gzip_release(void **ptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static long bytes_out;
|
||||||
|
static uch *output_data;
|
||||||
|
static const uint8_t *input_data;
|
||||||
|
static int input_len;
|
||||||
|
|
||||||
|
#include "inflate.c"
|
||||||
|
|
||||||
|
/* ===========================================================================
|
||||||
|
* Fill the input buffer. This is called only when the buffer is empty
|
||||||
|
* and at least one byte is really needed.
|
||||||
|
*/
|
||||||
|
static int fill_inbuf(void)
|
||||||
|
{
|
||||||
|
if (insize != 0) {
|
||||||
|
error("ran out of input data\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
inbuf = (uint8_t *)input_data;
|
||||||
|
insize = input_len;
|
||||||
|
inptr = 1;
|
||||||
|
return inbuf[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
static void flush_window(void)
|
||||||
|
{
|
||||||
|
memcpy(output_data, window, outcnt);
|
||||||
|
output_data += outcnt;
|
||||||
|
bytes_out += outcnt;
|
||||||
|
outcnt = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void error(char *x)
|
||||||
|
{
|
||||||
|
fatal("%s", x);
|
||||||
|
}
|
||||||
|
|
||||||
|
int do_gunzip(uint8_t *dest, const uint8_t *src, int src_len)
|
||||||
|
{
|
||||||
|
input_data = src;
|
||||||
|
input_len = src_len;
|
||||||
|
output_data = dest;
|
||||||
|
bytes_out = 0;
|
||||||
|
gunzip();
|
||||||
|
return bytes_out;
|
||||||
|
}
|
|
@ -0,0 +1,128 @@
|
||||||
|
/*
|
||||||
|
* linux/boot/head.S
|
||||||
|
*
|
||||||
|
* Copyright (C) 1991, 1992, 1993 Linus Torvalds
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* head.S contains the 32-bit startup code.
|
||||||
|
*
|
||||||
|
* NOTE!!! Startup happens at absolute address 0x00001000, which is also where
|
||||||
|
* the page directory will exist. The startup code will be overwritten by
|
||||||
|
* the page directory. [According to comments etc elsewhere on a compressed
|
||||||
|
* kernel it will end up at 0x1000 + 1Mb I hope so as I assume this. - AC]
|
||||||
|
*
|
||||||
|
* Page 0 is deliberately kept safe, since System Management Mode code in
|
||||||
|
* laptops may need to access the BIOS data stored there. This is also
|
||||||
|
* useful for future device drivers that either access the BIOS via VM86
|
||||||
|
* mode.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
|
||||||
|
*/
|
||||||
|
.text
|
||||||
|
|
||||||
|
#include <linux/linkage.h>
|
||||||
|
#include <asm/segment.h>
|
||||||
|
|
||||||
|
.globl startup_32
|
||||||
|
|
||||||
|
startup_32:
|
||||||
|
cld
|
||||||
|
cli
|
||||||
|
movl $(__KERNEL_DS),%eax
|
||||||
|
movl %eax,%ds
|
||||||
|
movl %eax,%es
|
||||||
|
movl %eax,%fs
|
||||||
|
movl %eax,%gs
|
||||||
|
|
||||||
|
lss SYMBOL_NAME(stack_start),%esp
|
||||||
|
xorl %eax,%eax
|
||||||
|
1: incl %eax # check that A20 really IS enabled
|
||||||
|
movl %eax,0x000000 # loop forever if it isn't
|
||||||
|
cmpl %eax,0x100000
|
||||||
|
je 1b
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize eflags. Some BIOS's leave bits like NT set. This would
|
||||||
|
* confuse the debugger if this code is traced.
|
||||||
|
* XXX - best to initialize before switching to protected mode.
|
||||||
|
*/
|
||||||
|
pushl $0
|
||||||
|
popfl
|
||||||
|
/*
|
||||||
|
* Clear BSS
|
||||||
|
*/
|
||||||
|
xorl %eax,%eax
|
||||||
|
movl $ SYMBOL_NAME(_edata),%edi
|
||||||
|
movl $ SYMBOL_NAME(_end),%ecx
|
||||||
|
subl %edi,%ecx
|
||||||
|
cld
|
||||||
|
rep
|
||||||
|
stosb
|
||||||
|
/*
|
||||||
|
* Do the decompression, and jump to the new kernel..
|
||||||
|
*/
|
||||||
|
subl $16,%esp # place for structure on the stack
|
||||||
|
movl %esp,%eax
|
||||||
|
pushl %esi # real mode pointer as second arg
|
||||||
|
pushl %eax # address of structure as first arg
|
||||||
|
call SYMBOL_NAME(compile_kernel)
|
||||||
|
orl %eax,%eax
|
||||||
|
jnz 3f
|
||||||
|
popl %esi # discard address
|
||||||
|
popl %esi # real mode pointer
|
||||||
|
xorl %ebx,%ebx
|
||||||
|
ljmp $(__KERNEL_CS), $0x100000
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We come here, if we were loaded high.
|
||||||
|
* We need to move the move-in-place routine down to 0x1000
|
||||||
|
* and then start it with the buffer addresses in registers,
|
||||||
|
* which we got from the stack.
|
||||||
|
*/
|
||||||
|
3:
|
||||||
|
movl $move_routine_start,%esi
|
||||||
|
movl $0x1000,%edi
|
||||||
|
movl $move_routine_end,%ecx
|
||||||
|
subl %esi,%ecx
|
||||||
|
addl $3,%ecx
|
||||||
|
shrl $2,%ecx
|
||||||
|
cld
|
||||||
|
rep
|
||||||
|
movsl
|
||||||
|
|
||||||
|
popl %esi # discard the address
|
||||||
|
popl %ebx # real mode pointer
|
||||||
|
popl %esi # low_buffer_start
|
||||||
|
popl %ecx # lcount
|
||||||
|
popl %edx # high_buffer_start
|
||||||
|
popl %eax # hcount
|
||||||
|
movl $0x100000,%edi
|
||||||
|
cli # make sure we don't get interrupted
|
||||||
|
ljmp $(__KERNEL_CS), $0x1000 # and jump to the move routine
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Routine (template) for moving the decompressed kernel in place,
|
||||||
|
* if we were high loaded. This _must_ PIC-code !
|
||||||
|
*/
|
||||||
|
move_routine_start:
|
||||||
|
movl %ecx,%ebp
|
||||||
|
shrl $2,%ecx
|
||||||
|
rep
|
||||||
|
movsl
|
||||||
|
movl %ebp,%ecx
|
||||||
|
andl $3,%ecx
|
||||||
|
rep
|
||||||
|
movsb
|
||||||
|
movl %edx,%esi
|
||||||
|
movl %eax,%ecx # NOTE: rep movsb won't move if %ecx == 0
|
||||||
|
addl $3,%ecx
|
||||||
|
shrl $2,%ecx
|
||||||
|
rep
|
||||||
|
movsl
|
||||||
|
movl %ebx,%esi # Restore setup pointer
|
||||||
|
xorl %ebx,%ebx
|
||||||
|
ljmp $(__KERNEL_CS), $0x100000
|
||||||
|
move_routine_end:
|
Binary file not shown.
|
@ -0,0 +1,492 @@
|
||||||
|
#include "tccboot.h"
|
||||||
|
|
||||||
|
//#define ROMFS_DEBUG
|
||||||
|
|
||||||
|
char msg_buf[1024];
|
||||||
|
|
||||||
|
void puts(const char *s)
|
||||||
|
{
|
||||||
|
putstr(s);
|
||||||
|
putstr("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
int printf(const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, fmt);
|
||||||
|
|
||||||
|
vsnprintf(msg_buf, sizeof(msg_buf), fmt, ap);
|
||||||
|
putstr(msg_buf);
|
||||||
|
va_end(ap);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE *stderr;
|
||||||
|
|
||||||
|
int fprintf(FILE *f, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, fmt);
|
||||||
|
|
||||||
|
vsnprintf(msg_buf, sizeof(msg_buf), fmt, ap);
|
||||||
|
putstr(msg_buf);
|
||||||
|
va_end(ap);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void getcwd(char *buf, size_t buf_size)
|
||||||
|
{
|
||||||
|
strcpy(buf, "/");
|
||||||
|
}
|
||||||
|
|
||||||
|
void fatal(const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, fmt);
|
||||||
|
|
||||||
|
putstr("tccboot: panic: ");
|
||||||
|
vsnprintf(msg_buf, sizeof(msg_buf), fmt, ap);
|
||||||
|
putstr(msg_buf);
|
||||||
|
putstr("\n");
|
||||||
|
va_end(ap);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********************************************************/
|
||||||
|
|
||||||
|
int errno;
|
||||||
|
|
||||||
|
long strtol(const char *nptr, char **endptr, int base)
|
||||||
|
{
|
||||||
|
return simple_strtol(nptr, endptr, base);
|
||||||
|
}
|
||||||
|
|
||||||
|
long long strtoll(const char *nptr, char **endptr, int base)
|
||||||
|
{
|
||||||
|
return simple_strtoll(nptr, endptr, base);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long strtoul(const char *nptr, char **endptr, int base)
|
||||||
|
{
|
||||||
|
return simple_strtoul(nptr, endptr, base);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long long strtoull(const char *nptr, char **endptr, int base)
|
||||||
|
{
|
||||||
|
return simple_strtoull(nptr, endptr, base);
|
||||||
|
}
|
||||||
|
|
||||||
|
int atoi(const char *s)
|
||||||
|
{
|
||||||
|
return strtol(s, NULL, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********************************************************/
|
||||||
|
|
||||||
|
int gettimeofday(struct timeval *tv, struct timezone *tz)
|
||||||
|
{
|
||||||
|
tv->tv_sec = 0;
|
||||||
|
tv->tv_usec = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
time_t time(time_t *t)
|
||||||
|
{
|
||||||
|
if (t)
|
||||||
|
*t = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct tm *localtime(const time_t *timep)
|
||||||
|
{
|
||||||
|
static struct tm static_tm;
|
||||||
|
return &static_tm;
|
||||||
|
}
|
||||||
|
|
||||||
|
int setjmp(jmp_buf buf)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void longjmp(jmp_buf buf, int val)
|
||||||
|
{
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********************************************************/
|
||||||
|
#define MALLOC_MAX_SIZE (128 * 1024 * 1024)
|
||||||
|
extern uint8_t _end;
|
||||||
|
uint8_t *malloc_ptr = &_end;
|
||||||
|
|
||||||
|
void *sbrk(int increment)
|
||||||
|
{
|
||||||
|
uint8_t *ptr, *new_ptr;
|
||||||
|
|
||||||
|
if (increment == 0)
|
||||||
|
return malloc_ptr;
|
||||||
|
ptr = malloc_ptr;
|
||||||
|
new_ptr = malloc_ptr + increment;
|
||||||
|
if (new_ptr > (&_end + MALLOC_MAX_SIZE)) {
|
||||||
|
errno = ENOMEM;
|
||||||
|
return (void *)-1;
|
||||||
|
}
|
||||||
|
malloc_ptr = new_ptr;
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
#define MALLOC_ALIGN 4096
|
||||||
|
|
||||||
|
void free(void *ptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void *realloc(void *oldptr, size_t size)
|
||||||
|
{
|
||||||
|
void *ptr;
|
||||||
|
if (size == 0) {
|
||||||
|
free(oldptr);
|
||||||
|
return NULL;
|
||||||
|
} else {
|
||||||
|
ptr = malloc(size);
|
||||||
|
/* XXX: incorrect */
|
||||||
|
if (oldptr) {
|
||||||
|
memcpy(ptr, oldptr, size);
|
||||||
|
free(oldptr);
|
||||||
|
}
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/**********************************************************/
|
||||||
|
|
||||||
|
uint8_t *romfs_base;
|
||||||
|
|
||||||
|
/* The basic structures of the romfs filesystem */
|
||||||
|
|
||||||
|
#define ROMBSIZE BLOCK_SIZE
|
||||||
|
#define ROMBSBITS BLOCK_SIZE_BITS
|
||||||
|
#define ROMBMASK (ROMBSIZE-1)
|
||||||
|
#define ROMFS_MAGIC 0x7275
|
||||||
|
|
||||||
|
#define ROMFS_MAXFN 128
|
||||||
|
|
||||||
|
#define __mkw(h,l) (((h)&0x00ff)<< 8|((l)&0x00ff))
|
||||||
|
#define __mkl(h,l) (((h)&0xffff)<<16|((l)&0xffff))
|
||||||
|
#define __mk4(a,b,c,d) htonl(__mkl(__mkw(a,b),__mkw(c,d)))
|
||||||
|
#define ROMSB_WORD0 __mk4('-','r','o','m')
|
||||||
|
#define ROMSB_WORD1 __mk4('1','f','s','-')
|
||||||
|
|
||||||
|
/* On-disk "super block" */
|
||||||
|
|
||||||
|
struct romfs_super_block {
|
||||||
|
uint32_t word0;
|
||||||
|
uint32_t word1;
|
||||||
|
uint32_t size;
|
||||||
|
uint32_t checksum;
|
||||||
|
char name[0]; /* volume name */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* On disk inode */
|
||||||
|
|
||||||
|
struct romfs_inode {
|
||||||
|
uint32_t next; /* low 4 bits see ROMFH_ */
|
||||||
|
uint32_t spec;
|
||||||
|
uint32_t size;
|
||||||
|
uint32_t checksum;
|
||||||
|
char name[0];
|
||||||
|
};
|
||||||
|
|
||||||
|
#define ROMFH_TYPE 7
|
||||||
|
#define ROMFH_HRD 0
|
||||||
|
#define ROMFH_DIR 1
|
||||||
|
#define ROMFH_REG 2
|
||||||
|
#define ROMFH_SYM 3
|
||||||
|
#define ROMFH_BLK 4
|
||||||
|
#define ROMFH_CHR 5
|
||||||
|
#define ROMFH_SCK 6
|
||||||
|
#define ROMFH_FIF 7
|
||||||
|
#define ROMFH_EXEC 8
|
||||||
|
|
||||||
|
/* Alignment */
|
||||||
|
|
||||||
|
#define ROMFH_ALIGN 16
|
||||||
|
|
||||||
|
#define MAX_FILE_HANDLES 256
|
||||||
|
|
||||||
|
typedef struct FileHandle {
|
||||||
|
uint8_t *base;
|
||||||
|
unsigned long size, max_size;
|
||||||
|
unsigned long pos;
|
||||||
|
int is_rw;
|
||||||
|
} FileHandle;
|
||||||
|
|
||||||
|
static FileHandle file_handles[MAX_FILE_HANDLES];
|
||||||
|
|
||||||
|
static uint8_t *output_base;
|
||||||
|
static size_t output_max_size, output_size;
|
||||||
|
static uint8_t output_filename[128];
|
||||||
|
|
||||||
|
void set_output_file(const char *filename,
|
||||||
|
uint8_t *base, size_t size)
|
||||||
|
{
|
||||||
|
strcpy(output_filename, filename);
|
||||||
|
output_base = base;
|
||||||
|
output_max_size = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
long get_output_file_size(void)
|
||||||
|
{
|
||||||
|
return output_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int get_file_handle(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i = 0; i < MAX_FILE_HANDLES; i++) {
|
||||||
|
if (!file_handles[i].base)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
errno = ENOMEM;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int open(const char *filename, int access, ...)
|
||||||
|
{
|
||||||
|
struct romfs_super_block *sb;
|
||||||
|
unsigned long addr, next;
|
||||||
|
struct romfs_inode *inode;
|
||||||
|
int type, fd, len;
|
||||||
|
char dir[1024];
|
||||||
|
const char *p, *r;
|
||||||
|
|
||||||
|
if (access & O_CREAT) {
|
||||||
|
/* specific case for file creation */
|
||||||
|
if (strcmp(filename, output_filename) != 0)
|
||||||
|
return -EPERM;
|
||||||
|
fd = get_file_handle();
|
||||||
|
if (fd < 0)
|
||||||
|
return fd;
|
||||||
|
file_handles[fd].base = output_base;
|
||||||
|
file_handles[fd].max_size = output_max_size;
|
||||||
|
file_handles[fd].is_rw = 1;
|
||||||
|
file_handles[fd].pos = 0;
|
||||||
|
file_handles[fd].size = 0;
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
show_filename(filename);
|
||||||
|
|
||||||
|
sb = (void *)romfs_base;
|
||||||
|
if (sb->word0 != ROMSB_WORD0 ||
|
||||||
|
sb->word1 != ROMSB_WORD1)
|
||||||
|
goto fail;
|
||||||
|
addr = ((unsigned long)sb->name + strlen(sb->name) + 1 + ROMFH_ALIGN - 1) &
|
||||||
|
~(ROMFH_ALIGN - 1);
|
||||||
|
inode = (void *)addr;
|
||||||
|
|
||||||
|
/* search the directory */
|
||||||
|
p = filename;
|
||||||
|
while (*p == '/')
|
||||||
|
p++;
|
||||||
|
for(;;) {
|
||||||
|
r = strchr(p, '/');
|
||||||
|
if (!r)
|
||||||
|
break;
|
||||||
|
len = r - p;
|
||||||
|
if (len > sizeof(dir) - 1)
|
||||||
|
goto fail;
|
||||||
|
memcpy(dir, p, len);
|
||||||
|
dir[len] = '\0';
|
||||||
|
p = r + 1;
|
||||||
|
#ifdef ROMFS_DEBUG
|
||||||
|
printf("dir=%s\n", dir);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for(;;) {
|
||||||
|
next = ntohl(inode->next);
|
||||||
|
type = next & 0xf;
|
||||||
|
next &= ~0xf;
|
||||||
|
if (!strcmp(dir, inode->name)) {
|
||||||
|
#ifdef ROMFS_DEBUG
|
||||||
|
printf("dirname=%s type=0x%x\n", inode->name, type);
|
||||||
|
#endif
|
||||||
|
if ((type & ROMFH_TYPE) == ROMFH_DIR) {
|
||||||
|
chdir:
|
||||||
|
addr = ((unsigned long)inode->name + strlen(inode->name) +
|
||||||
|
1 + ROMFH_ALIGN - 1) &
|
||||||
|
~(ROMFH_ALIGN - 1);
|
||||||
|
inode = (void *)addr;
|
||||||
|
break;
|
||||||
|
} else if ((type & ROMFH_TYPE) == ROMFH_HRD) {
|
||||||
|
addr = ntohl(inode->spec);
|
||||||
|
inode = (void *)(romfs_base + addr);
|
||||||
|
next = ntohl(inode->next);
|
||||||
|
type = next & 0xf;
|
||||||
|
if ((type & ROMFH_TYPE) != ROMFH_DIR)
|
||||||
|
goto fail;
|
||||||
|
goto chdir;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (next == 0)
|
||||||
|
goto fail;
|
||||||
|
inode = (void *)(romfs_base + next);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(;;) {
|
||||||
|
next = ntohl(inode->next);
|
||||||
|
type = next & 0xf;
|
||||||
|
next &= ~0xf;
|
||||||
|
#ifdef ROMFS_DEBUG
|
||||||
|
printf("name=%s type=0x%x\n", inode->name, type);
|
||||||
|
#endif
|
||||||
|
if ((type & ROMFH_TYPE) == ROMFH_REG) {
|
||||||
|
if (!strcmp(p, inode->name)) {
|
||||||
|
fd = get_file_handle();
|
||||||
|
if (fd < 0)
|
||||||
|
return fd;
|
||||||
|
addr = ((unsigned long)inode->name + strlen(inode->name) +
|
||||||
|
1 + ROMFH_ALIGN - 1) &
|
||||||
|
~(ROMFH_ALIGN - 1);
|
||||||
|
file_handles[fd].base = (void *)addr;
|
||||||
|
file_handles[fd].is_rw = 0;
|
||||||
|
file_handles[fd].pos = 0;
|
||||||
|
file_handles[fd].size = ntohl(inode->size);
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (next == 0)
|
||||||
|
break;
|
||||||
|
inode = (void *)(romfs_base + next);
|
||||||
|
}
|
||||||
|
fail:
|
||||||
|
errno = ENOENT;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int read(int fd, void *buf, size_t size)
|
||||||
|
{
|
||||||
|
FileHandle *fh = &file_handles[fd];
|
||||||
|
int len;
|
||||||
|
|
||||||
|
len = fh->size - fh->pos;
|
||||||
|
if (len > (int)size)
|
||||||
|
len = size;
|
||||||
|
memcpy(buf, fh->base + fh->pos, len);
|
||||||
|
fh->pos += len;
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
int write(int fd, const void *buf, size_t size)
|
||||||
|
{
|
||||||
|
FileHandle *fh = &file_handles[fd];
|
||||||
|
int len;
|
||||||
|
|
||||||
|
if (!fh->is_rw)
|
||||||
|
return -EIO;
|
||||||
|
len = fh->max_size - fh->pos;
|
||||||
|
if ((int)size > len) {
|
||||||
|
errno = ENOSPC;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
memcpy(fh->base + fh->pos, buf, size);
|
||||||
|
fh->pos += size;
|
||||||
|
if (fh->pos > fh->size) {
|
||||||
|
fh->size = fh->pos;
|
||||||
|
output_size = fh->pos;
|
||||||
|
}
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
long lseek(int fd, long offset, int whence)
|
||||||
|
{
|
||||||
|
FileHandle *fh = &file_handles[fd];
|
||||||
|
|
||||||
|
switch(whence) {
|
||||||
|
case SEEK_SET:
|
||||||
|
break;
|
||||||
|
case SEEK_END:
|
||||||
|
offset += fh->size;
|
||||||
|
break;
|
||||||
|
case SEEK_CUR:
|
||||||
|
offset += fh->pos;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (offset < 0) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
fh->pos = offset;
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
int close(int fd)
|
||||||
|
{
|
||||||
|
FileHandle *fh = &file_handles[fd];
|
||||||
|
fh->base = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********************************************************/
|
||||||
|
|
||||||
|
float strtof(const char *nptr, char **endptr)
|
||||||
|
{
|
||||||
|
fatal("unimplemented: %s", __func__ );
|
||||||
|
}
|
||||||
|
|
||||||
|
long double strtold(const char *nptr, char **endptr)
|
||||||
|
{
|
||||||
|
fatal("unimplemented: %s", __func__ );
|
||||||
|
}
|
||||||
|
|
||||||
|
double ldexp(double x, int exp)
|
||||||
|
{
|
||||||
|
fatal("unimplemented: %s", __func__ );
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE *fopen(const char *path, const char *mode)
|
||||||
|
{
|
||||||
|
fatal("unimplemented: %s", __func__ );
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE *fdopen(int fildes, const char *mode)
|
||||||
|
{
|
||||||
|
FILE *f;
|
||||||
|
f = malloc(sizeof(FILE));
|
||||||
|
f->fd = fildes;
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fclose(FILE *stream)
|
||||||
|
{
|
||||||
|
close(stream->fd);
|
||||||
|
free(stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
if (nmemb == 1) {
|
||||||
|
ret = write(stream->fd, ptr, size);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
} else {
|
||||||
|
ret = write(stream->fd, ptr, size * nmemb);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
if (nmemb != 0)
|
||||||
|
ret /= nmemb;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fputc(int c, FILE *stream)
|
||||||
|
{
|
||||||
|
uint8_t ch = c;
|
||||||
|
write(stream->fd, &ch, 1);
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,551 @@
|
||||||
|
#
|
||||||
|
# Automatically generated by make menuconfig: don't edit
|
||||||
|
#
|
||||||
|
CONFIG_X86=y
|
||||||
|
# CONFIG_SBUS is not set
|
||||||
|
CONFIG_UID16=y
|
||||||
|
|
||||||
|
#
|
||||||
|
# Code maturity level options
|
||||||
|
#
|
||||||
|
# CONFIG_EXPERIMENTAL is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Loadable module support
|
||||||
|
#
|
||||||
|
# CONFIG_MODULES is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Processor type and features
|
||||||
|
#
|
||||||
|
# CONFIG_M386 is not set
|
||||||
|
CONFIG_M486=y
|
||||||
|
# CONFIG_M586 is not set
|
||||||
|
# CONFIG_M586TSC is not set
|
||||||
|
# CONFIG_M586MMX is not set
|
||||||
|
# CONFIG_M686 is not set
|
||||||
|
# CONFIG_MPENTIUMIII is not set
|
||||||
|
# CONFIG_MPENTIUM4 is not set
|
||||||
|
# CONFIG_MK6 is not set
|
||||||
|
# CONFIG_MK7 is not set
|
||||||
|
# CONFIG_MK8 is not set
|
||||||
|
# CONFIG_MELAN is not set
|
||||||
|
# CONFIG_MCRUSOE is not set
|
||||||
|
# CONFIG_MWINCHIPC6 is not set
|
||||||
|
# CONFIG_MWINCHIP2 is not set
|
||||||
|
# CONFIG_MWINCHIP3D is not set
|
||||||
|
# CONFIG_MCYRIXIII is not set
|
||||||
|
# CONFIG_MVIAC3_2 is not set
|
||||||
|
CONFIG_X86_WP_WORKS_OK=y
|
||||||
|
CONFIG_X86_INVLPG=y
|
||||||
|
CONFIG_X86_CMPXCHG=y
|
||||||
|
CONFIG_X86_XADD=y
|
||||||
|
CONFIG_X86_BSWAP=y
|
||||||
|
CONFIG_X86_POPAD_OK=y
|
||||||
|
# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
|
||||||
|
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
|
||||||
|
CONFIG_X86_L1_CACHE_SHIFT=4
|
||||||
|
CONFIG_X86_USE_STRING_486=y
|
||||||
|
CONFIG_X86_ALIGNMENT_16=y
|
||||||
|
CONFIG_X86_PPRO_FENCE=y
|
||||||
|
# CONFIG_X86_F00F_WORKS_OK is not set
|
||||||
|
# CONFIG_X86_MCE is not set
|
||||||
|
# CONFIG_TOSHIBA is not set
|
||||||
|
# CONFIG_I8K is not set
|
||||||
|
# CONFIG_MICROCODE is not set
|
||||||
|
# CONFIG_X86_MSR is not set
|
||||||
|
# CONFIG_X86_CPUID is not set
|
||||||
|
CONFIG_NOHIGHMEM=y
|
||||||
|
# CONFIG_HIGHMEM4G is not set
|
||||||
|
# CONFIG_HIGHMEM64G is not set
|
||||||
|
# CONFIG_HIGHMEM is not set
|
||||||
|
# CONFIG_MATH_EMULATION is not set
|
||||||
|
# CONFIG_MTRR is not set
|
||||||
|
# CONFIG_SMP is not set
|
||||||
|
# CONFIG_X86_UP_APIC is not set
|
||||||
|
# CONFIG_X86_UP_IOAPIC is not set
|
||||||
|
# CONFIG_X86_TSC_DISABLE is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# General setup
|
||||||
|
#
|
||||||
|
CONFIG_NET=y
|
||||||
|
# CONFIG_PCI is not set
|
||||||
|
# CONFIG_ISA is not set
|
||||||
|
# CONFIG_EISA is not set
|
||||||
|
# CONFIG_MCA is not set
|
||||||
|
# CONFIG_HOTPLUG is not set
|
||||||
|
# CONFIG_PCMCIA is not set
|
||||||
|
# CONFIG_HOTPLUG_PCI is not set
|
||||||
|
CONFIG_SYSVIPC=y
|
||||||
|
# CONFIG_BSD_PROCESS_ACCT is not set
|
||||||
|
CONFIG_SYSCTL=y
|
||||||
|
CONFIG_KCORE_ELF=y
|
||||||
|
# CONFIG_KCORE_AOUT is not set
|
||||||
|
# CONFIG_BINFMT_AOUT is not set
|
||||||
|
CONFIG_BINFMT_ELF=y
|
||||||
|
# CONFIG_BINFMT_MISC is not set
|
||||||
|
# CONFIG_OOM_KILLER is not set
|
||||||
|
# CONFIG_PM is not set
|
||||||
|
# CONFIG_APM is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# ACPI Support
|
||||||
|
#
|
||||||
|
# CONFIG_ACPI is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Memory Technology Devices (MTD)
|
||||||
|
#
|
||||||
|
# CONFIG_MTD is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Parallel port support
|
||||||
|
#
|
||||||
|
# CONFIG_PARPORT is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Plug and Play configuration
|
||||||
|
#
|
||||||
|
# CONFIG_PNP is not set
|
||||||
|
# CONFIG_ISAPNP is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Block devices
|
||||||
|
#
|
||||||
|
CONFIG_BLK_DEV_FD=y
|
||||||
|
# CONFIG_BLK_DEV_XD is not set
|
||||||
|
# CONFIG_PARIDE is not set
|
||||||
|
# CONFIG_BLK_CPQ_DA is not set
|
||||||
|
# CONFIG_BLK_CPQ_CISS_DA is not set
|
||||||
|
# CONFIG_CISS_SCSI_TAPE is not set
|
||||||
|
# CONFIG_CISS_MONITOR_THREAD is not set
|
||||||
|
# CONFIG_BLK_DEV_DAC960 is not set
|
||||||
|
# CONFIG_BLK_DEV_UMEM is not set
|
||||||
|
CONFIG_BLK_DEV_LOOP=y
|
||||||
|
# CONFIG_BLK_DEV_NBD is not set
|
||||||
|
CONFIG_BLK_DEV_RAM=y
|
||||||
|
CONFIG_BLK_DEV_RAM_SIZE=4096
|
||||||
|
CONFIG_BLK_DEV_INITRD=y
|
||||||
|
# CONFIG_BLK_STATS is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Multi-device support (RAID and LVM)
|
||||||
|
#
|
||||||
|
# CONFIG_MD is not set
|
||||||
|
# CONFIG_BLK_DEV_MD is not set
|
||||||
|
# CONFIG_MD_LINEAR is not set
|
||||||
|
# CONFIG_MD_RAID0 is not set
|
||||||
|
# CONFIG_MD_RAID1 is not set
|
||||||
|
# CONFIG_MD_RAID5 is not set
|
||||||
|
# CONFIG_MD_MULTIPATH is not set
|
||||||
|
# CONFIG_BLK_DEV_LVM is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Networking options
|
||||||
|
#
|
||||||
|
CONFIG_PACKET=y
|
||||||
|
# CONFIG_PACKET_MMAP is not set
|
||||||
|
# CONFIG_NETLINK_DEV is not set
|
||||||
|
# CONFIG_NETFILTER is not set
|
||||||
|
# CONFIG_FILTER is not set
|
||||||
|
CONFIG_UNIX=y
|
||||||
|
CONFIG_INET=y
|
||||||
|
CONFIG_IP_MULTICAST=y
|
||||||
|
# CONFIG_IP_ADVANCED_ROUTER is not set
|
||||||
|
# CONFIG_IP_PNP is not set
|
||||||
|
# CONFIG_NET_IPIP is not set
|
||||||
|
# CONFIG_NET_IPGRE is not set
|
||||||
|
# CONFIG_IP_MROUTE is not set
|
||||||
|
# CONFIG_INET_ECN is not set
|
||||||
|
# CONFIG_SYN_COOKIES is not set
|
||||||
|
# CONFIG_VLAN_8021Q is not set
|
||||||
|
# CONFIG_IPX is not set
|
||||||
|
# CONFIG_ATALK is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Appletalk devices
|
||||||
|
#
|
||||||
|
# CONFIG_DEV_APPLETALK is not set
|
||||||
|
# CONFIG_DECNET is not set
|
||||||
|
# CONFIG_BRIDGE is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# QoS and/or fair queueing
|
||||||
|
#
|
||||||
|
# CONFIG_NET_SCHED is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Network testing
|
||||||
|
#
|
||||||
|
# CONFIG_NET_PKTGEN is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Telephony Support
|
||||||
|
#
|
||||||
|
# CONFIG_PHONE is not set
|
||||||
|
# CONFIG_PHONE_IXJ is not set
|
||||||
|
# CONFIG_PHONE_IXJ_PCMCIA is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# ATA/IDE/MFM/RLL support
|
||||||
|
#
|
||||||
|
CONFIG_IDE=y
|
||||||
|
|
||||||
|
#
|
||||||
|
# IDE, ATA and ATAPI Block devices
|
||||||
|
#
|
||||||
|
CONFIG_BLK_DEV_IDE=y
|
||||||
|
# CONFIG_BLK_DEV_HD_IDE is not set
|
||||||
|
# CONFIG_BLK_DEV_HD is not set
|
||||||
|
CONFIG_BLK_DEV_IDEDISK=y
|
||||||
|
CONFIG_IDEDISK_MULTI_MODE=y
|
||||||
|
# CONFIG_IDEDISK_STROKE is not set
|
||||||
|
# CONFIG_BLK_DEV_IDECS is not set
|
||||||
|
CONFIG_BLK_DEV_IDECD=y
|
||||||
|
# CONFIG_BLK_DEV_IDETAPE is not set
|
||||||
|
# CONFIG_BLK_DEV_IDEFLOPPY is not set
|
||||||
|
# CONFIG_BLK_DEV_IDESCSI is not set
|
||||||
|
# CONFIG_IDE_TASK_IOCTL is not set
|
||||||
|
# CONFIG_BLK_DEV_CMD640 is not set
|
||||||
|
# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
|
||||||
|
# CONFIG_BLK_DEV_ISAPNP is not set
|
||||||
|
# CONFIG_IDE_CHIPSETS is not set
|
||||||
|
# CONFIG_IDEDMA_AUTO is not set
|
||||||
|
# CONFIG_DMA_NONPCI is not set
|
||||||
|
# CONFIG_BLK_DEV_ATARAID is not set
|
||||||
|
# CONFIG_BLK_DEV_ATARAID_PDC is not set
|
||||||
|
# CONFIG_BLK_DEV_ATARAID_HPT is not set
|
||||||
|
# CONFIG_BLK_DEV_ATARAID_MEDLEY is not set
|
||||||
|
# CONFIG_BLK_DEV_ATARAID_SII is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# SCSI support
|
||||||
|
#
|
||||||
|
# CONFIG_SCSI is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Fusion MPT device support
|
||||||
|
#
|
||||||
|
# CONFIG_FUSION is not set
|
||||||
|
# CONFIG_FUSION_BOOT is not set
|
||||||
|
# CONFIG_FUSION_ISENSE is not set
|
||||||
|
# CONFIG_FUSION_CTL is not set
|
||||||
|
# CONFIG_FUSION_LAN is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# I2O device support
|
||||||
|
#
|
||||||
|
# CONFIG_I2O is not set
|
||||||
|
# CONFIG_I2O_BLOCK is not set
|
||||||
|
# CONFIG_I2O_LAN is not set
|
||||||
|
# CONFIG_I2O_SCSI is not set
|
||||||
|
# CONFIG_I2O_PROC is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Network device support
|
||||||
|
#
|
||||||
|
CONFIG_NETDEVICES=y
|
||||||
|
|
||||||
|
#
|
||||||
|
# ARCnet devices
|
||||||
|
#
|
||||||
|
# CONFIG_ARCNET is not set
|
||||||
|
CONFIG_DUMMY=y
|
||||||
|
# CONFIG_BONDING is not set
|
||||||
|
# CONFIG_EQUALIZER is not set
|
||||||
|
# CONFIG_TUN is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Ethernet (10 or 100Mbit)
|
||||||
|
#
|
||||||
|
CONFIG_NET_ETHERNET=y
|
||||||
|
# CONFIG_SUNLANCE is not set
|
||||||
|
# CONFIG_SUNBMAC is not set
|
||||||
|
# CONFIG_SUNQE is not set
|
||||||
|
# CONFIG_SUNGEM is not set
|
||||||
|
# CONFIG_NET_VENDOR_3COM is not set
|
||||||
|
# CONFIG_LANCE is not set
|
||||||
|
# CONFIG_NET_VENDOR_SMC is not set
|
||||||
|
# CONFIG_NET_VENDOR_RACAL is not set
|
||||||
|
# CONFIG_NET_ISA is not set
|
||||||
|
# CONFIG_NET_PCI is not set
|
||||||
|
# CONFIG_NET_POCKET is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Ethernet (1000 Mbit)
|
||||||
|
#
|
||||||
|
# CONFIG_ACENIC is not set
|
||||||
|
# CONFIG_DL2K is not set
|
||||||
|
# CONFIG_E1000 is not set
|
||||||
|
# CONFIG_MYRI_SBUS is not set
|
||||||
|
# CONFIG_NS83820 is not set
|
||||||
|
# CONFIG_HAMACHI is not set
|
||||||
|
# CONFIG_YELLOWFIN is not set
|
||||||
|
# CONFIG_R8169 is not set
|
||||||
|
# CONFIG_SK98LIN is not set
|
||||||
|
# CONFIG_TIGON3 is not set
|
||||||
|
# CONFIG_FDDI is not set
|
||||||
|
# CONFIG_PLIP is not set
|
||||||
|
# CONFIG_PPP is not set
|
||||||
|
# CONFIG_SLIP is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Wireless LAN (non-hamradio)
|
||||||
|
#
|
||||||
|
# CONFIG_NET_RADIO is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Token Ring devices
|
||||||
|
#
|
||||||
|
# CONFIG_TR is not set
|
||||||
|
# CONFIG_NET_FC is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Wan interfaces
|
||||||
|
#
|
||||||
|
# CONFIG_WAN is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Amateur Radio support
|
||||||
|
#
|
||||||
|
# CONFIG_HAMRADIO is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# IrDA (infrared) support
|
||||||
|
#
|
||||||
|
# CONFIG_IRDA is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# ISDN subsystem
|
||||||
|
#
|
||||||
|
# CONFIG_ISDN is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Input core support
|
||||||
|
#
|
||||||
|
# CONFIG_INPUT is not set
|
||||||
|
# CONFIG_INPUT_KEYBDEV is not set
|
||||||
|
# CONFIG_INPUT_MOUSEDEV is not set
|
||||||
|
# CONFIG_INPUT_JOYDEV is not set
|
||||||
|
# CONFIG_INPUT_EVDEV is not set
|
||||||
|
# CONFIG_INPUT_UINPUT is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Character devices
|
||||||
|
#
|
||||||
|
CONFIG_VT=y
|
||||||
|
CONFIG_VT_CONSOLE=y
|
||||||
|
CONFIG_SERIAL=y
|
||||||
|
CONFIG_SERIAL_CONSOLE=y
|
||||||
|
# CONFIG_SERIAL_EXTENDED is not set
|
||||||
|
# CONFIG_SERIAL_NONSTANDARD is not set
|
||||||
|
CONFIG_UNIX98_PTYS=y
|
||||||
|
CONFIG_UNIX98_PTY_COUNT=256
|
||||||
|
|
||||||
|
#
|
||||||
|
# I2C support
|
||||||
|
#
|
||||||
|
# CONFIG_I2C is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Mice
|
||||||
|
#
|
||||||
|
# CONFIG_BUSMOUSE is not set
|
||||||
|
CONFIG_MOUSE=y
|
||||||
|
CONFIG_PSMOUSE=y
|
||||||
|
# CONFIG_82C710_MOUSE is not set
|
||||||
|
# CONFIG_PC110_PAD is not set
|
||||||
|
# CONFIG_MK712_MOUSE is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Joysticks
|
||||||
|
#
|
||||||
|
# CONFIG_INPUT_GAMEPORT is not set
|
||||||
|
# CONFIG_QIC02_TAPE is not set
|
||||||
|
# CONFIG_IPMI_HANDLER is not set
|
||||||
|
# CONFIG_IPMI_PANIC_EVENT is not set
|
||||||
|
# CONFIG_IPMI_DEVICE_INTERFACE is not set
|
||||||
|
# CONFIG_IPMI_KCS is not set
|
||||||
|
# CONFIG_IPMI_WATCHDOG is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Watchdog Cards
|
||||||
|
#
|
||||||
|
# CONFIG_WATCHDOG is not set
|
||||||
|
# CONFIG_SCx200 is not set
|
||||||
|
# CONFIG_SCx200_GPIO is not set
|
||||||
|
# CONFIG_AMD_RNG is not set
|
||||||
|
# CONFIG_INTEL_RNG is not set
|
||||||
|
# CONFIG_HW_RANDOM is not set
|
||||||
|
# CONFIG_AMD_PM768 is not set
|
||||||
|
# CONFIG_NVRAM is not set
|
||||||
|
# CONFIG_RTC is not set
|
||||||
|
# CONFIG_DTLK is not set
|
||||||
|
# CONFIG_R3964 is not set
|
||||||
|
# CONFIG_APPLICOM is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Ftape, the floppy tape device driver
|
||||||
|
#
|
||||||
|
# CONFIG_FTAPE is not set
|
||||||
|
# CONFIG_AGP is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Direct Rendering Manager (XFree86 DRI support)
|
||||||
|
#
|
||||||
|
# CONFIG_DRM is not set
|
||||||
|
# CONFIG_MWAVE is not set
|
||||||
|
# CONFIG_OBMOUSE is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Multimedia devices
|
||||||
|
#
|
||||||
|
# CONFIG_VIDEO_DEV is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# File systems
|
||||||
|
#
|
||||||
|
# CONFIG_QUOTA is not set
|
||||||
|
# CONFIG_QFMT_V2 is not set
|
||||||
|
# CONFIG_AUTOFS_FS is not set
|
||||||
|
# CONFIG_AUTOFS4_FS is not set
|
||||||
|
# CONFIG_REISERFS_FS is not set
|
||||||
|
# CONFIG_REISERFS_CHECK is not set
|
||||||
|
# CONFIG_REISERFS_PROC_INFO is not set
|
||||||
|
# CONFIG_ADFS_FS is not set
|
||||||
|
# CONFIG_ADFS_FS_RW is not set
|
||||||
|
# CONFIG_AFFS_FS is not set
|
||||||
|
# CONFIG_HFS_FS is not set
|
||||||
|
# CONFIG_HFSPLUS_FS is not set
|
||||||
|
# CONFIG_BEFS_FS is not set
|
||||||
|
# CONFIG_BEFS_DEBUG is not set
|
||||||
|
# CONFIG_BFS_FS is not set
|
||||||
|
# CONFIG_EXT3_FS is not set
|
||||||
|
# CONFIG_JBD is not set
|
||||||
|
# CONFIG_JBD_DEBUG is not set
|
||||||
|
# CONFIG_FAT_FS is not set
|
||||||
|
# CONFIG_MSDOS_FS is not set
|
||||||
|
# CONFIG_UMSDOS_FS is not set
|
||||||
|
# CONFIG_VFAT_FS is not set
|
||||||
|
# CONFIG_EFS_FS is not set
|
||||||
|
# CONFIG_JFFS_FS is not set
|
||||||
|
# CONFIG_JFFS2_FS is not set
|
||||||
|
# CONFIG_CRAMFS is not set
|
||||||
|
CONFIG_TMPFS=y
|
||||||
|
CONFIG_RAMFS=y
|
||||||
|
CONFIG_ISO9660_FS=y
|
||||||
|
# CONFIG_JOLIET is not set
|
||||||
|
# CONFIG_ZISOFS is not set
|
||||||
|
# CONFIG_JFS_FS is not set
|
||||||
|
# CONFIG_JFS_DEBUG is not set
|
||||||
|
# CONFIG_JFS_STATISTICS is not set
|
||||||
|
# CONFIG_MINIX_FS is not set
|
||||||
|
# CONFIG_VXFS_FS is not set
|
||||||
|
# CONFIG_NTFS_FS is not set
|
||||||
|
# CONFIG_NTFS_RW is not set
|
||||||
|
# CONFIG_HPFS_FS is not set
|
||||||
|
CONFIG_PROC_FS=y
|
||||||
|
# CONFIG_DEVFS_FS is not set
|
||||||
|
# CONFIG_DEVFS_MOUNT is not set
|
||||||
|
# CONFIG_DEVFS_DEBUG is not set
|
||||||
|
CONFIG_DEVPTS_FS=y
|
||||||
|
# CONFIG_QNX4FS_FS is not set
|
||||||
|
# CONFIG_QNX4FS_RW is not set
|
||||||
|
CONFIG_ROMFS_FS=y
|
||||||
|
CONFIG_EXT2_FS=y
|
||||||
|
# CONFIG_SYSV_FS is not set
|
||||||
|
# CONFIG_UDF_FS is not set
|
||||||
|
# CONFIG_UDF_RW is not set
|
||||||
|
# CONFIG_UFS_FS is not set
|
||||||
|
# CONFIG_UFS_FS_WRITE is not set
|
||||||
|
# CONFIG_XFS_FS is not set
|
||||||
|
# CONFIG_XFS_QUOTA is not set
|
||||||
|
# CONFIG_XFS_RT is not set
|
||||||
|
# CONFIG_XFS_TRACE is not set
|
||||||
|
# CONFIG_XFS_DEBUG is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Network File Systems
|
||||||
|
#
|
||||||
|
# CONFIG_CODA_FS is not set
|
||||||
|
# CONFIG_INTERMEZZO_FS is not set
|
||||||
|
# CONFIG_NFS_FS is not set
|
||||||
|
# CONFIG_NFS_V3 is not set
|
||||||
|
# CONFIG_NFS_DIRECTIO is not set
|
||||||
|
# CONFIG_ROOT_NFS is not set
|
||||||
|
# CONFIG_NFSD is not set
|
||||||
|
# CONFIG_NFSD_V3 is not set
|
||||||
|
# CONFIG_NFSD_TCP is not set
|
||||||
|
# CONFIG_SUNRPC is not set
|
||||||
|
# CONFIG_LOCKD is not set
|
||||||
|
# CONFIG_SMB_FS is not set
|
||||||
|
# CONFIG_NCP_FS is not set
|
||||||
|
# CONFIG_NCPFS_PACKET_SIGNING is not set
|
||||||
|
# CONFIG_NCPFS_IOCTL_LOCKING is not set
|
||||||
|
# CONFIG_NCPFS_STRONG is not set
|
||||||
|
# CONFIG_NCPFS_NFS_NS is not set
|
||||||
|
# CONFIG_NCPFS_OS2_NS is not set
|
||||||
|
# CONFIG_NCPFS_SMALLDOS is not set
|
||||||
|
# CONFIG_NCPFS_NLS is not set
|
||||||
|
# CONFIG_NCPFS_EXTRAS is not set
|
||||||
|
# CONFIG_ZISOFS_FS is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Partition Types
|
||||||
|
#
|
||||||
|
# CONFIG_PARTITION_ADVANCED is not set
|
||||||
|
CONFIG_MSDOS_PARTITION=y
|
||||||
|
# CONFIG_SMB_NLS is not set
|
||||||
|
# CONFIG_NLS is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Console drivers
|
||||||
|
#
|
||||||
|
CONFIG_VGA_CONSOLE=y
|
||||||
|
# CONFIG_VIDEO_SELECT is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Sound
|
||||||
|
#
|
||||||
|
# CONFIG_SOUND is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# USB support
|
||||||
|
#
|
||||||
|
# CONFIG_USB is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Support for USB gadgets
|
||||||
|
#
|
||||||
|
# CONFIG_USB_GADGET is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bluetooth support
|
||||||
|
#
|
||||||
|
# CONFIG_BLUEZ is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Kernel hacking
|
||||||
|
#
|
||||||
|
CONFIG_DEBUG_KERNEL=y
|
||||||
|
# CONFIG_DEBUG_STACKOVERFLOW is not set
|
||||||
|
# CONFIG_DEBUG_HIGHMEM is not set
|
||||||
|
# CONFIG_DEBUG_SLAB is not set
|
||||||
|
# CONFIG_DEBUG_IOVIRT is not set
|
||||||
|
# CONFIG_MAGIC_SYSRQ is not set
|
||||||
|
# CONFIG_DEBUG_SPINLOCK is not set
|
||||||
|
# CONFIG_FRAME_POINTER is not set
|
||||||
|
CONFIG_LOG_BUF_SHIFT=0
|
||||||
|
|
||||||
|
#
|
||||||
|
# Cryptographic options
|
||||||
|
#
|
||||||
|
# CONFIG_CRYPTO is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Library routines
|
||||||
|
#
|
||||||
|
CONFIG_CRC32=y
|
||||||
|
# CONFIG_ZLIB_INFLATE is not set
|
||||||
|
# CONFIG_ZLIB_DEFLATE is not set
|
|
@ -0,0 +1,427 @@
|
||||||
|
diff -ruNw /tmp/linux-2.4.26/arch/i386/kernel/entry.S linux-2.4.26/arch/i386/kernel/entry.S
|
||||||
|
--- /tmp/linux-2.4.26/arch/i386/kernel/entry.S 2003-06-13 16:51:29.000000000 +0200
|
||||||
|
+++ linux-2.4.26/arch/i386/kernel/entry.S 2004-10-23 22:19:02.000000000 +0200
|
||||||
|
@@ -1,3 +1,4 @@
|
||||||
|
+#define __ASSEMBLY__
|
||||||
|
/*
|
||||||
|
* linux/arch/i386/entry.S
|
||||||
|
*
|
||||||
|
@@ -664,6 +665,21 @@
|
||||||
|
.long SYMBOL_NAME(sys_ni_syscall) /* sys_remap_file_pages */
|
||||||
|
.long SYMBOL_NAME(sys_ni_syscall) /* sys_set_tid_address */
|
||||||
|
|
||||||
|
+#if 0
|
||||||
|
.rept NR_syscalls-(.-sys_call_table)/4
|
||||||
|
.long SYMBOL_NAME(sys_ni_syscall)
|
||||||
|
.endr
|
||||||
|
+#else
|
||||||
|
+ .long SYMBOL_NAME(sys_ni_syscall)
|
||||||
|
+ .long SYMBOL_NAME(sys_ni_syscall)
|
||||||
|
+ .long SYMBOL_NAME(sys_ni_syscall)
|
||||||
|
+ .long SYMBOL_NAME(sys_ni_syscall)
|
||||||
|
+ .long SYMBOL_NAME(sys_ni_syscall)
|
||||||
|
+ .long SYMBOL_NAME(sys_ni_syscall)
|
||||||
|
+ .long SYMBOL_NAME(sys_ni_syscall)
|
||||||
|
+ .long SYMBOL_NAME(sys_ni_syscall)
|
||||||
|
+ .long SYMBOL_NAME(sys_ni_syscall)
|
||||||
|
+ .long SYMBOL_NAME(sys_ni_syscall)
|
||||||
|
+ .long SYMBOL_NAME(sys_ni_syscall)
|
||||||
|
+ .long SYMBOL_NAME(sys_ni_syscall)
|
||||||
|
+#endif
|
||||||
|
diff -ruNw /tmp/linux-2.4.26/arch/i386/kernel/head.S linux-2.4.26/arch/i386/kernel/head.S
|
||||||
|
--- /tmp/linux-2.4.26/arch/i386/kernel/head.S 2003-11-28 19:26:19.000000000 +0100
|
||||||
|
+++ linux-2.4.26/arch/i386/kernel/head.S 2004-10-25 21:18:30.000000000 +0200
|
||||||
|
@@ -1,3 +1,4 @@
|
||||||
|
+#define __ASSEMBLY__
|
||||||
|
/*
|
||||||
|
* linux/arch/i386/kernel/head.S -- the 32-bit startup code.
|
||||||
|
*
|
||||||
|
@@ -41,6 +42,8 @@
|
||||||
|
*
|
||||||
|
* On entry, %esi points to the real-mode code as a 32-bit pointer.
|
||||||
|
*/
|
||||||
|
+.globl _start
|
||||||
|
+_start:
|
||||||
|
startup_32:
|
||||||
|
/*
|
||||||
|
* Set segments to known values
|
||||||
|
diff -ruNw /tmp/linux-2.4.26/arch/i386/kernel/i387.c linux-2.4.26/arch/i386/kernel/i387.c
|
||||||
|
--- /tmp/linux-2.4.26/arch/i386/kernel/i387.c 2003-08-25 13:44:39.000000000 +0200
|
||||||
|
+++ linux-2.4.26/arch/i386/kernel/i387.c 2004-10-14 04:17:43.000000000 +0200
|
||||||
|
@@ -25,7 +25,7 @@
|
||||||
|
#define HAVE_HWFP 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
-static union i387_union empty_fpu_state;
|
||||||
|
+union i387_union empty_fpu_state;
|
||||||
|
|
||||||
|
void __init boot_init_fpu(void)
|
||||||
|
{
|
||||||
|
diff -ruNw /tmp/linux-2.4.26/arch/i386/kernel/process.c linux-2.4.26/arch/i386/kernel/process.c
|
||||||
|
--- /tmp/linux-2.4.26/arch/i386/kernel/process.c 2004-02-18 14:36:30.000000000 +0100
|
||||||
|
+++ linux-2.4.26/arch/i386/kernel/process.c 2004-10-25 21:30:36.000000000 +0200
|
||||||
|
@@ -52,7 +52,7 @@
|
||||||
|
|
||||||
|
#include <linux/irq.h>
|
||||||
|
|
||||||
|
-asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
|
||||||
|
+asmlinkage void ret_from_fork(void) /* __asm__("ret_from_fork") */ ;
|
||||||
|
|
||||||
|
int hlt_counter;
|
||||||
|
|
||||||
|
@@ -217,7 +217,7 @@
|
||||||
|
0x000092000100ffffULL /* 16-bit real-mode 64k data at 0x00000100 */
|
||||||
|
};
|
||||||
|
|
||||||
|
-static struct
|
||||||
|
+struct
|
||||||
|
{
|
||||||
|
unsigned short size __attribute__ ((packed));
|
||||||
|
unsigned long long * base __attribute__ ((packed));
|
||||||
|
diff -ruNw /tmp/linux-2.4.26/arch/i386/kernel/setup.c linux-2.4.26/arch/i386/kernel/setup.c
|
||||||
|
--- /tmp/linux-2.4.26/arch/i386/kernel/setup.c 2004-04-14 15:05:25.000000000 +0200
|
||||||
|
+++ linux-2.4.26/arch/i386/kernel/setup.c 2004-10-17 19:38:37.000000000 +0200
|
||||||
|
@@ -1392,7 +1392,7 @@
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern void vide(void);
|
||||||
|
-__asm__(".align 4\nvide: ret");
|
||||||
|
+__asm__(".align 4\n.globl vide\nvide: ret");
|
||||||
|
|
||||||
|
static int __init init_amd(struct cpuinfo_x86 *c)
|
||||||
|
{
|
||||||
|
diff -ruNw /tmp/linux-2.4.26/arch/i386/mm/init.c linux-2.4.26/arch/i386/mm/init.c
|
||||||
|
--- /tmp/linux-2.4.26/arch/i386/mm/init.c 2004-04-14 15:05:25.000000000 +0200
|
||||||
|
+++ linux-2.4.26/arch/i386/mm/init.c 2004-10-23 22:35:47.000000000 +0200
|
||||||
|
@@ -36,6 +36,7 @@
|
||||||
|
#include <asm/fixmap.h>
|
||||||
|
#include <asm/e820.h>
|
||||||
|
#include <asm/apic.h>
|
||||||
|
+#include <asm-generic/tlb.h>
|
||||||
|
#include <asm/tlb.h>
|
||||||
|
|
||||||
|
mmu_gather_t mmu_gathers[NR_CPUS];
|
||||||
|
diff -ruNw /tmp/linux-2.4.26/arch/i386/mm/pageattr.c linux-2.4.26/arch/i386/mm/pageattr.c
|
||||||
|
--- /tmp/linux-2.4.26/arch/i386/mm/pageattr.c 2002-11-29 00:53:09.000000000 +0100
|
||||||
|
+++ linux-2.4.26/arch/i386/mm/pageattr.c 2004-10-14 00:43:58.000000000 +0200
|
||||||
|
@@ -44,8 +44,12 @@
|
||||||
|
addr = address & LARGE_PAGE_MASK;
|
||||||
|
pbase = (pte_t *)page_address(base);
|
||||||
|
for (i = 0; i < PTRS_PER_PTE; i++, addr += PAGE_SIZE) {
|
||||||
|
- pbase[i] = mk_pte_phys(addr,
|
||||||
|
- addr == address ? prot : PAGE_KERNEL);
|
||||||
|
+ pgprot_t prot1;
|
||||||
|
+ if (addr == address)
|
||||||
|
+ prot1 = prot;
|
||||||
|
+ else
|
||||||
|
+ prot1 = PAGE_KERNEL;
|
||||||
|
+ pbase[i] = mk_pte_phys(addr, prot1);
|
||||||
|
}
|
||||||
|
return base;
|
||||||
|
}
|
||||||
|
diff -ruNw /tmp/linux-2.4.26/drivers/ide/ide-lib.c linux-2.4.26/drivers/ide/ide-lib.c
|
||||||
|
--- /tmp/linux-2.4.26/drivers/ide/ide-lib.c 2003-06-13 16:51:33.000000000 +0200
|
||||||
|
+++ linux-2.4.26/drivers/ide/ide-lib.c 2004-10-23 23:00:51.000000000 +0200
|
||||||
|
@@ -171,7 +171,7 @@
|
||||||
|
BUG();
|
||||||
|
return min(speed, speed_max[mode]);
|
||||||
|
#else /* !CONFIG_BLK_DEV_IDEDMA */
|
||||||
|
- return min(speed, XFER_PIO_4);
|
||||||
|
+ return min((int)speed, XFER_PIO_4);
|
||||||
|
#endif /* CONFIG_BLK_DEV_IDEDMA */
|
||||||
|
}
|
||||||
|
|
||||||
|
diff -ruNw /tmp/linux-2.4.26/fs/partitions/efi.h linux-2.4.26/fs/partitions/efi.h
|
||||||
|
--- /tmp/linux-2.4.26/fs/partitions/efi.h 2003-08-25 13:44:43.000000000 +0200
|
||||||
|
+++ linux-2.4.26/fs/partitions/efi.h 2004-10-25 21:32:29.000000000 +0200
|
||||||
|
@@ -85,9 +85,13 @@
|
||||||
|
} __attribute__ ((packed)) gpt_header;
|
||||||
|
|
||||||
|
typedef struct _gpt_entry_attributes {
|
||||||
|
+#if 0
|
||||||
|
u64 required_to_function:1;
|
||||||
|
u64 reserved:47;
|
||||||
|
u64 type_guid_specific:16;
|
||||||
|
+#else
|
||||||
|
+ u64 required;
|
||||||
|
+#endif
|
||||||
|
} __attribute__ ((packed)) gpt_entry_attributes;
|
||||||
|
|
||||||
|
typedef struct _gpt_entry {
|
||||||
|
diff -ruNw /tmp/linux-2.4.26/include/asm-i386/bugs.h linux-2.4.26/include/asm-i386/bugs.h
|
||||||
|
--- /tmp/linux-2.4.26/include/asm-i386/bugs.h 2002-08-03 02:39:45.000000000 +0200
|
||||||
|
+++ linux-2.4.26/include/asm-i386/bugs.h 2004-10-25 21:31:34.000000000 +0200
|
||||||
|
@@ -50,8 +50,8 @@
|
||||||
|
|
||||||
|
__setup("no387", no_387);
|
||||||
|
|
||||||
|
-static double __initdata x = 4195835.0;
|
||||||
|
-static double __initdata y = 3145727.0;
|
||||||
|
+double __initdata x = 4195835.0;
|
||||||
|
+double __initdata y = 3145727.0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This used to check for exceptions..
|
||||||
|
diff -ruNw /tmp/linux-2.4.26/include/asm-i386/byteorder.h linux-2.4.26/include/asm-i386/byteorder.h
|
||||||
|
--- /tmp/linux-2.4.26/include/asm-i386/byteorder.h 2003-06-13 16:51:38.000000000 +0200
|
||||||
|
+++ linux-2.4.26/include/asm-i386/byteorder.h 2004-10-23 23:08:08.000000000 +0200
|
||||||
|
@@ -42,8 +42,10 @@
|
||||||
|
__u64 u;
|
||||||
|
} v;
|
||||||
|
v.u = val;
|
||||||
|
-#ifdef CONFIG_X86_BSWAP
|
||||||
|
- asm("bswapl %0 ; bswapl %1 ; xchgl %0,%1"
|
||||||
|
+#if defined(CONFIG_X86_BSWAP) && 0
|
||||||
|
+ /* XXX: constraint bug
|
||||||
|
+ bswap %eax ; bswap (%ecx) ; xchgl %eax,(%ecx) */
|
||||||
|
+ asm("bswap %0 ; bswap %1 ; xchgl %0,%1"
|
||||||
|
: "=r" (v.s.a), "=r" (v.s.b)
|
||||||
|
: "0" (v.s.a), "1" (v.s.b));
|
||||||
|
#else
|
||||||
|
diff -ruNw /tmp/linux-2.4.26/include/asm-i386/hw_irq.h linux-2.4.26/include/asm-i386/hw_irq.h
|
||||||
|
--- /tmp/linux-2.4.26/include/asm-i386/hw_irq.h 2003-08-25 13:44:43.000000000 +0200
|
||||||
|
+++ linux-2.4.26/include/asm-i386/hw_irq.h 2004-10-23 23:08:08.000000000 +0200
|
||||||
|
@@ -156,6 +156,7 @@
|
||||||
|
asmlinkage void call_do_IRQ(void); \
|
||||||
|
__asm__( \
|
||||||
|
"\n" __ALIGN_STR"\n" \
|
||||||
|
+ ".globl common_interrupt\n\t" \
|
||||||
|
"common_interrupt:\n\t" \
|
||||||
|
SAVE_ALL \
|
||||||
|
SYMBOL_NAME_STR(call_do_IRQ)":\n\t" \
|
||||||
|
@@ -176,6 +177,7 @@
|
||||||
|
asmlinkage void IRQ_NAME(nr); \
|
||||||
|
__asm__( \
|
||||||
|
"\n"__ALIGN_STR"\n" \
|
||||||
|
+".globl " SYMBOL_NAME_STR(IRQ) #nr "_interrupt\n\t"\
|
||||||
|
SYMBOL_NAME_STR(IRQ) #nr "_interrupt:\n\t" \
|
||||||
|
"pushl $"#nr"-256\n\t" \
|
||||||
|
"jmp common_interrupt");
|
||||||
|
diff -ruNw /tmp/linux-2.4.26/include/asm-i386/page.h linux-2.4.26/include/asm-i386/page.h
|
||||||
|
--- /tmp/linux-2.4.26/include/asm-i386/page.h 2002-08-03 02:39:45.000000000 +0200
|
||||||
|
+++ linux-2.4.26/include/asm-i386/page.h 2004-10-23 23:08:08.000000000 +0200
|
||||||
|
@@ -95,7 +95,7 @@
|
||||||
|
* undefined" opcode for parsing in the trap handler.
|
||||||
|
*/
|
||||||
|
|
||||||
|
-#if 1 /* Set to zero for a slightly smaller kernel */
|
||||||
|
+#if 0 /* Set to zero for a slightly smaller kernel */
|
||||||
|
#define BUG() \
|
||||||
|
__asm__ __volatile__( "ud2\n" \
|
||||||
|
"\t.word %c0\n" \
|
||||||
|
diff -ruNw /tmp/linux-2.4.26/include/asm-i386/processor.h linux-2.4.26/include/asm-i386/processor.h
|
||||||
|
--- /tmp/linux-2.4.26/include/asm-i386/processor.h 2004-02-18 14:36:32.000000000 +0100
|
||||||
|
+++ linux-2.4.26/include/asm-i386/processor.h 2004-10-23 23:08:08.000000000 +0200
|
||||||
|
@@ -300,6 +300,7 @@
|
||||||
|
long st_space[32]; /* 8*16 bytes for each FP-reg = 128 bytes */
|
||||||
|
long xmm_space[32]; /* 8*16 bytes for each XMM-reg = 128 bytes */
|
||||||
|
long padding[56];
|
||||||
|
+ int dummy[0] __attribute__ ((aligned (16)));
|
||||||
|
} __attribute__ ((aligned (16)));
|
||||||
|
|
||||||
|
struct i387_soft_struct {
|
||||||
|
diff -ruNw /tmp/linux-2.4.26/include/asm-i386/semaphore.h linux-2.4.26/include/asm-i386/semaphore.h
|
||||||
|
--- /tmp/linux-2.4.26/include/asm-i386/semaphore.h 2002-11-29 00:53:15.000000000 +0100
|
||||||
|
+++ linux-2.4.26/include/asm-i386/semaphore.h 2004-10-25 21:31:34.000000000 +0200
|
||||||
|
@@ -207,7 +207,7 @@
|
||||||
|
"2:\tcall __up_wakeup\n\t"
|
||||||
|
"jmp 1b\n"
|
||||||
|
LOCK_SECTION_END
|
||||||
|
- ".subsection 0\n"
|
||||||
|
+ /* ".subsection 0\n" */
|
||||||
|
:"=m" (sem->count)
|
||||||
|
:"c" (sem)
|
||||||
|
:"memory");
|
||||||
|
diff -ruNw /tmp/linux-2.4.26/include/asm-i386/string.h linux-2.4.26/include/asm-i386/string.h
|
||||||
|
--- /tmp/linux-2.4.26/include/asm-i386/string.h 2001-11-22 20:46:18.000000000 +0100
|
||||||
|
+++ linux-2.4.26/include/asm-i386/string.h 2004-10-23 23:08:08.000000000 +0200
|
||||||
|
@@ -178,7 +178,7 @@
|
||||||
|
"leal -1(%%esi),%0\n"
|
||||||
|
"2:\ttestb %%al,%%al\n\t"
|
||||||
|
"jne 1b"
|
||||||
|
- :"=g" (__res), "=&S" (d0), "=&a" (d1) :"0" (0),"1" (s),"2" (c));
|
||||||
|
+ :"=r" (__res), "=&S" (d0), "=&a" (d1) :"0" (0),"1" (s),"2" (c));
|
||||||
|
return __res;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff -ruNw /tmp/linux-2.4.26/include/asm-i386/system.h linux-2.4.26/include/asm-i386/system.h
|
||||||
|
--- /tmp/linux-2.4.26/include/asm-i386/system.h 2004-04-14 15:05:40.000000000 +0200
|
||||||
|
+++ linux-2.4.26/include/asm-i386/system.h 2004-10-25 21:30:22.000000000 +0200
|
||||||
|
@@ -28,7 +28,7 @@
|
||||||
|
"popl %%esi\n\t" \
|
||||||
|
:"=m" (prev->thread.esp),"=m" (prev->thread.eip), \
|
||||||
|
"=b" (last) \
|
||||||
|
- :"m" (next->thread.esp),"m" (next->thread.eip), \
|
||||||
|
+ :"g" (next->thread.esp),"g" (next->thread.eip), \
|
||||||
|
"a" (prev), "d" (next), \
|
||||||
|
"b" (prev)); \
|
||||||
|
} while (0)
|
||||||
|
@@ -313,7 +313,7 @@
|
||||||
|
#define set_wmb(var, value) do { var = value; wmb(); } while (0)
|
||||||
|
|
||||||
|
/* interrupt control.. */
|
||||||
|
-#define __save_flags(x) __asm__ __volatile__("pushfl ; popl %0":"=g" (x): /* no input */)
|
||||||
|
+#define __save_flags(x) __asm__ __volatile__("pushfl ; popl %0" : "=g" (x) /* no input */)
|
||||||
|
#define __restore_flags(x) __asm__ __volatile__("pushl %0 ; popfl": /* no output */ :"g" (x):"memory", "cc")
|
||||||
|
#define __cli() __asm__ __volatile__("cli": : :"memory")
|
||||||
|
#define __sti() __asm__ __volatile__("sti": : :"memory")
|
||||||
|
diff -ruNw /tmp/linux-2.4.26/include/linux/byteorder/generic.h linux-2.4.26/include/linux/byteorder/generic.h
|
||||||
|
--- /tmp/linux-2.4.26/include/linux/byteorder/generic.h 2003-11-28 19:26:21.000000000 +0100
|
||||||
|
+++ linux-2.4.26/include/linux/byteorder/generic.h 2004-10-17 22:09:20.000000000 +0200
|
||||||
|
@@ -86,8 +86,8 @@
|
||||||
|
*/
|
||||||
|
#define cpu_to_le64 __cpu_to_le64
|
||||||
|
#define le64_to_cpu __le64_to_cpu
|
||||||
|
-#define cpu_to_le32 __cpu_to_le32
|
||||||
|
-#define le32_to_cpu __le32_to_cpu
|
||||||
|
+#define cpu_to_le32(x) __cpu_to_le32(x)
|
||||||
|
+#define le32_to_cpu(x) __le32_to_cpu(x)
|
||||||
|
#define cpu_to_le16 __cpu_to_le16
|
||||||
|
#define le16_to_cpu __le16_to_cpu
|
||||||
|
#define cpu_to_be64 __cpu_to_be64
|
||||||
|
diff -ruNw /tmp/linux-2.4.26/include/linux/linkage.h linux-2.4.26/include/linux/linkage.h
|
||||||
|
--- /tmp/linux-2.4.26/include/linux/linkage.h 2000-12-11 21:49:54.000000000 +0100
|
||||||
|
+++ linux-2.4.26/include/linux/linkage.h 2004-10-23 23:08:08.000000000 +0200
|
||||||
|
@@ -19,11 +19,7 @@
|
||||||
|
|
||||||
|
#define SYMBOL_NAME_STR(X) #X
|
||||||
|
#define SYMBOL_NAME(X) X
|
||||||
|
-#ifdef __STDC__
|
||||||
|
-#define SYMBOL_NAME_LABEL(X) X##:
|
||||||
|
-#else
|
||||||
|
-#define SYMBOL_NAME_LABEL(X) X/**/:
|
||||||
|
-#endif
|
||||||
|
+#define SYMBOL_NAME_LABEL(X) X:
|
||||||
|
|
||||||
|
#ifdef __arm__
|
||||||
|
#define __ALIGN .align 0
|
||||||
|
diff -ruNw /tmp/linux-2.4.26/include/linux/spinlock.h linux-2.4.26/include/linux/spinlock.h
|
||||||
|
--- /tmp/linux-2.4.26/include/linux/spinlock.h 2004-02-18 14:36:32.000000000 +0100
|
||||||
|
+++ linux-2.4.26/include/linux/spinlock.h 2004-10-25 21:31:34.000000000 +0200
|
||||||
|
@@ -41,6 +41,7 @@
|
||||||
|
|
||||||
|
#include <linux/stringify.h>
|
||||||
|
|
||||||
|
+#if 0
|
||||||
|
#define LOCK_SECTION_NAME \
|
||||||
|
".text.lock." __stringify(KBUILD_BASENAME)
|
||||||
|
|
||||||
|
@@ -51,6 +52,11 @@
|
||||||
|
LOCK_SECTION_NAME ":\n\t" \
|
||||||
|
".endif\n\t"
|
||||||
|
|
||||||
|
+#else
|
||||||
|
+#define LOCK_SECTION_NAME ".text.lock"
|
||||||
|
+#define LOCK_SECTION_START(extra) ".section " LOCK_SECTION_NAME "\n\t"
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
#define LOCK_SECTION_END \
|
||||||
|
".previous\n\t"
|
||||||
|
|
||||||
|
diff -ruNw /tmp/linux-2.4.26/include/linux/wait.h linux-2.4.26/include/linux/wait.h
|
||||||
|
--- /tmp/linux-2.4.26/include/linux/wait.h 2003-08-25 13:44:44.000000000 +0200
|
||||||
|
+++ linux-2.4.26/include/linux/wait.h 2004-10-25 21:31:34.000000000 +0200
|
||||||
|
@@ -64,14 +64,14 @@
|
||||||
|
# define wq_lock_t spinlock_t
|
||||||
|
# define WAITQUEUE_RW_LOCK_UNLOCKED SPIN_LOCK_UNLOCKED
|
||||||
|
|
||||||
|
-# define wq_read_lock spin_lock
|
||||||
|
-# define wq_read_lock_irqsave spin_lock_irqsave
|
||||||
|
-# define wq_read_unlock spin_unlock
|
||||||
|
-# define wq_read_unlock_irqrestore spin_unlock_irqrestore
|
||||||
|
-# define wq_write_lock_irq spin_lock_irq
|
||||||
|
-# define wq_write_lock_irqsave spin_lock_irqsave
|
||||||
|
-# define wq_write_unlock_irqrestore spin_unlock_irqrestore
|
||||||
|
-# define wq_write_unlock spin_unlock
|
||||||
|
+# define wq_read_lock(lock) spin_lock(lock)
|
||||||
|
+# define wq_read_lock_irqsave(lock, flags) spin_lock_irqsave(lock, flags)
|
||||||
|
+# define wq_read_unlock(lock) spin_unlock(lock)
|
||||||
|
+# define wq_read_unlock_irqrestore(lock, flags) spin_unlock_irqrestore(lock, flags)
|
||||||
|
+# define wq_write_lock_irq(lock) spin_lock_irq(lock)
|
||||||
|
+# define wq_write_lock_irqsave(lock, flags) spin_lock_irqsave(lock, flags)
|
||||||
|
+# define wq_write_unlock_irqrestore(lock, flags) spin_unlock_irqrestore(lock, flags)
|
||||||
|
+# define wq_write_unlock(lock) spin_unlock(lock)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct __wait_queue_head {
|
||||||
|
diff -ruNw /tmp/linux-2.4.26/net/core/dev.c linux-2.4.26/net/core/dev.c
|
||||||
|
--- /tmp/linux-2.4.26/net/core/dev.c 2004-04-14 15:05:41.000000000 +0200
|
||||||
|
+++ linux-2.4.26/net/core/dev.c 2004-10-14 03:27:45.000000000 +0200
|
||||||
|
@@ -2013,8 +2013,17 @@
|
||||||
|
ret = 0;
|
||||||
|
if ((old_flags^flags)&IFF_UP) /* Bit is different ? */
|
||||||
|
{
|
||||||
|
- ret = ((old_flags & IFF_UP) ? dev_close : dev_open)(dev);
|
||||||
|
+ int (*dev_func)(struct net_device *);
|
||||||
|
|
||||||
|
+#if 0
|
||||||
|
+ ret = ((old_flags & IFF_UP) ? dev_close : dev_open)(dev);
|
||||||
|
+#else
|
||||||
|
+ if (old_flags & IFF_UP)
|
||||||
|
+ dev_func = dev_close;
|
||||||
|
+ else
|
||||||
|
+ dev_func = dev_open;
|
||||||
|
+ ret = dev_func(dev);
|
||||||
|
+#endif
|
||||||
|
if (ret == 0)
|
||||||
|
dev_mc_upload(dev);
|
||||||
|
}
|
||||||
|
diff -ruNw /tmp/linux-2.4.26/net/ipv4/raw.c linux-2.4.26/net/ipv4/raw.c
|
||||||
|
--- /tmp/linux-2.4.26/net/ipv4/raw.c 2003-08-25 13:44:44.000000000 +0200
|
||||||
|
+++ linux-2.4.26/net/ipv4/raw.c 2004-10-23 22:53:26.000000000 +0200
|
||||||
|
@@ -311,6 +311,10 @@
|
||||||
|
u32 daddr;
|
||||||
|
u8 tos;
|
||||||
|
int err;
|
||||||
|
+ int (*getfrag)(const void *,
|
||||||
|
+ char *,
|
||||||
|
+ unsigned int,
|
||||||
|
+ unsigned int);
|
||||||
|
|
||||||
|
/* This check is ONLY to check for arithmetic overflow
|
||||||
|
on integer(!) len. Not more! Real check will be made
|
||||||
|
@@ -426,8 +430,11 @@
|
||||||
|
rfh.dst = &rt->u.dst;
|
||||||
|
if (!ipc.addr)
|
||||||
|
ipc.addr = rt->rt_dst;
|
||||||
|
- err = ip_build_xmit(sk, sk->protinfo.af_inet.hdrincl ? raw_getrawfrag :
|
||||||
|
- raw_getfrag, &rfh, len, &ipc, rt, msg->msg_flags);
|
||||||
|
+ if (sk->protinfo.af_inet.hdrincl)
|
||||||
|
+ getfrag =raw_getrawfrag;
|
||||||
|
+ else
|
||||||
|
+ getfrag = raw_getfrag;
|
||||||
|
+ err = ip_build_xmit(sk, getfrag, &rfh, len, &ipc, rt, msg->msg_flags);
|
||||||
|
|
||||||
|
done:
|
||||||
|
if (free)
|
||||||
|
diff -ruNw /tmp/linux-2.4.26/net/ipv4/udp.c linux-2.4.26/net/ipv4/udp.c
|
||||||
|
--- /tmp/linux-2.4.26/net/ipv4/udp.c 2004-04-14 15:05:41.000000000 +0200
|
||||||
|
+++ linux-2.4.26/net/ipv4/udp.c 2004-10-23 22:54:30.000000000 +0200
|
||||||
|
@@ -441,6 +441,10 @@
|
||||||
|
u32 daddr;
|
||||||
|
u8 tos;
|
||||||
|
int err;
|
||||||
|
+ int (*getfrag)(const void *,
|
||||||
|
+ char *,
|
||||||
|
+ unsigned int,
|
||||||
|
+ unsigned int);
|
||||||
|
|
||||||
|
/* This check is ONLY to check for arithmetic overflow
|
||||||
|
on integer(!) len. Not more! Real check will be made
|
||||||
|
@@ -560,11 +564,12 @@
|
||||||
|
/* RFC1122: OK. Provides the checksumming facility (MUST) as per */
|
||||||
|
/* 4.1.3.4. It's configurable by the application via setsockopt() */
|
||||||
|
/* (MAY) and it defaults to on (MUST). */
|
||||||
|
-
|
||||||
|
+ if (sk->no_check == UDP_CSUM_NOXMIT)
|
||||||
|
+ getfrag = udp_getfrag_nosum;
|
||||||
|
+ else
|
||||||
|
+ getfrag = udp_getfrag;
|
||||||
|
err = ip_build_xmit(sk,
|
||||||
|
- (sk->no_check == UDP_CSUM_NOXMIT ?
|
||||||
|
- udp_getfrag_nosum :
|
||||||
|
- udp_getfrag),
|
||||||
|
+ getfrag,
|
||||||
|
&ufh, ulen, &ipc, rt, msg->msg_flags);
|
||||||
|
|
||||||
|
out:
|
|
@ -0,0 +1,253 @@
|
||||||
|
#include "tccboot.h"
|
||||||
|
#include <linux/tty.h>
|
||||||
|
#include <asm/io.h>
|
||||||
|
|
||||||
|
#define TCCARGS_FILE "/boot/tccargs"
|
||||||
|
#define KERNEL_MAX_SIZE (8 * 1024 * 1024)
|
||||||
|
#define INITRD_MAX_SIZE (20 * 1024 * 1024)
|
||||||
|
#define INITRD_MIN_ADDR 0x800000
|
||||||
|
#define KERNEL_FILENAME "kernel"
|
||||||
|
|
||||||
|
//#define DEBUG_INITRD_ADDR
|
||||||
|
|
||||||
|
#define MAX_ARGS 1024
|
||||||
|
|
||||||
|
struct moveparams {
|
||||||
|
uint8_t *low_buffer_start; int lcount;
|
||||||
|
uint8_t *high_buffer_start; int hcount;
|
||||||
|
};
|
||||||
|
|
||||||
|
static unsigned char *real_mode; /* Pointer to real-mode data */
|
||||||
|
#define EXT_MEM_K (*(unsigned short *)(real_mode + 0x2))
|
||||||
|
#ifndef STANDARD_MEMORY_BIOS_CALL
|
||||||
|
#define ALT_MEM_K (*(unsigned long *)(real_mode + 0x1e0))
|
||||||
|
#endif
|
||||||
|
#define SCREEN_INFO (*(struct screen_info *)(real_mode+0))
|
||||||
|
#define INITRD_START (*(unsigned long *) (real_mode+0x218))
|
||||||
|
#define INITRD_SIZE (*(unsigned long *) (real_mode+0x21c))
|
||||||
|
|
||||||
|
#define STACK_SIZE (256 * 1024)
|
||||||
|
|
||||||
|
long user_stack [STACK_SIZE];
|
||||||
|
|
||||||
|
struct {
|
||||||
|
long * a;
|
||||||
|
short b;
|
||||||
|
} stack_start = { & user_stack [STACK_SIZE] , __KERNEL_DS };
|
||||||
|
|
||||||
|
|
||||||
|
static char *vidmem = (char *)0xb8000;
|
||||||
|
static int vidport;
|
||||||
|
static int lines, cols;
|
||||||
|
|
||||||
|
void video_init(void)
|
||||||
|
{
|
||||||
|
if (SCREEN_INFO.orig_video_mode == 7) {
|
||||||
|
vidmem = (char *) 0xb0000;
|
||||||
|
vidport = 0x3b4;
|
||||||
|
} else {
|
||||||
|
vidmem = (char *) 0xb8000;
|
||||||
|
vidport = 0x3d4;
|
||||||
|
}
|
||||||
|
|
||||||
|
lines = SCREEN_INFO.orig_video_lines;
|
||||||
|
cols = SCREEN_INFO.orig_video_cols;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void scroll(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
memcpy ( vidmem, vidmem + cols * 2, ( lines - 1 ) * cols * 2 );
|
||||||
|
for ( i = ( lines - 1 ) * cols * 2; i < lines * cols * 2; i += 2 )
|
||||||
|
vidmem[i] = ' ';
|
||||||
|
}
|
||||||
|
|
||||||
|
void putstr(const char *s)
|
||||||
|
{
|
||||||
|
int x,y,pos;
|
||||||
|
char c;
|
||||||
|
|
||||||
|
x = SCREEN_INFO.orig_x;
|
||||||
|
y = SCREEN_INFO.orig_y;
|
||||||
|
|
||||||
|
while ( ( c = *s++ ) != '\0' ) {
|
||||||
|
if ( c == '\n' ) {
|
||||||
|
x = 0;
|
||||||
|
if ( ++y >= lines ) {
|
||||||
|
scroll();
|
||||||
|
y--;
|
||||||
|
}
|
||||||
|
} else if (c == '\r') {
|
||||||
|
x = 0;
|
||||||
|
} else {
|
||||||
|
vidmem [ ( x + cols * y ) * 2 ] = c;
|
||||||
|
if ( ++x >= cols ) {
|
||||||
|
x = 0;
|
||||||
|
if ( ++y >= lines ) {
|
||||||
|
scroll();
|
||||||
|
y--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SCREEN_INFO.orig_x = x;
|
||||||
|
SCREEN_INFO.orig_y = y;
|
||||||
|
|
||||||
|
pos = (x + cols * y) * 2; /* Update cursor position */
|
||||||
|
outb_p(14, vidport);
|
||||||
|
outb_p(0xff & (pos >> 9), vidport+1);
|
||||||
|
outb_p(15, vidport);
|
||||||
|
outb_p(0xff & (pos >> 1), vidport+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void exit(int val)
|
||||||
|
{
|
||||||
|
printf("\n\n -- System halted");
|
||||||
|
while (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *tcc_args[MAX_ARGS];
|
||||||
|
|
||||||
|
static int expand_args(char ***pargv, const char *str)
|
||||||
|
{
|
||||||
|
const char *s1;
|
||||||
|
char **argv, *arg;
|
||||||
|
int argc, len;
|
||||||
|
|
||||||
|
argc = 0;
|
||||||
|
argv = tcc_args;
|
||||||
|
argv[argc++] = "tcc";
|
||||||
|
for(;;) {
|
||||||
|
while (isspace(*str))
|
||||||
|
str++;
|
||||||
|
if (*str == '\0')
|
||||||
|
break;
|
||||||
|
if (*str == '#') {
|
||||||
|
while (*str != '\n')
|
||||||
|
str++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
s1 = str;
|
||||||
|
while (*str != '\0' && !isspace(*str))
|
||||||
|
str++;
|
||||||
|
len = str - s1;
|
||||||
|
arg = malloc(len + 1);
|
||||||
|
memcpy(arg, s1, len);
|
||||||
|
arg[len] = '\0';
|
||||||
|
argv[argc++] = arg;
|
||||||
|
}
|
||||||
|
*pargv = argv;
|
||||||
|
return argc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void show_filename(const char *filename)
|
||||||
|
{
|
||||||
|
int len;
|
||||||
|
static int counter;
|
||||||
|
char counter_ch[4] = "-\\|/";
|
||||||
|
|
||||||
|
len = strlen(filename);
|
||||||
|
if (len >= 2 && filename[len - 2] == '.' && filename[len - 1] == 'c') {
|
||||||
|
printf("%c %-50s\r", counter_ch[counter], filename);
|
||||||
|
counter = (counter + 1) & 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int compile_kernel(struct moveparams *mv, void *rmode)
|
||||||
|
{
|
||||||
|
int fd, len;
|
||||||
|
char *args_buf;
|
||||||
|
char **argv;
|
||||||
|
int argc, ret, romfs_len;
|
||||||
|
uint8_t *kernel_ptr, *initrd_ptr;
|
||||||
|
unsigned long romfs_base1;
|
||||||
|
|
||||||
|
real_mode = rmode;
|
||||||
|
|
||||||
|
video_init();
|
||||||
|
|
||||||
|
/* this is risky, but normally the initrd is not mapped inside the
|
||||||
|
malloc structures. However, it can overlap with its new
|
||||||
|
location */
|
||||||
|
if (!INITRD_SIZE || !INITRD_START)
|
||||||
|
fatal("the kernel source must be in a ROMFS filesystem stored as Initial Ram Disk (INITRD)");
|
||||||
|
len = INITRD_SIZE;
|
||||||
|
/* NOTE: it is very important to move initrd first to avoid
|
||||||
|
destroying it later */
|
||||||
|
initrd_ptr = memalign(16, len);
|
||||||
|
memmove(initrd_ptr, (void *)INITRD_START, len);
|
||||||
|
if (initrd_ptr[0] == 037 && ((initrd_ptr[1] == 0213) ||
|
||||||
|
(initrd_ptr[1] == 0236))) {
|
||||||
|
printf("Decompressing initrd...\n");
|
||||||
|
romfs_base = memalign(16, INITRD_MAX_SIZE);
|
||||||
|
romfs_len = do_gunzip(romfs_base, initrd_ptr, len);
|
||||||
|
/* realloc it to minimize memory usage */
|
||||||
|
romfs_base = realloc(romfs_base, romfs_len);
|
||||||
|
free(initrd_ptr);
|
||||||
|
} else {
|
||||||
|
romfs_base = initrd_ptr;
|
||||||
|
romfs_len = len;
|
||||||
|
}
|
||||||
|
|
||||||
|
kernel_ptr = malloc(KERNEL_MAX_SIZE);
|
||||||
|
set_output_file("kernel", kernel_ptr, KERNEL_MAX_SIZE);
|
||||||
|
|
||||||
|
#ifdef DEBUG_INITRD_ADDR
|
||||||
|
printf("romfs_base=%p romfs_len=%d kernel_ptr=%p\n",
|
||||||
|
romfs_base, romfs_len, kernel_ptr);
|
||||||
|
#endif
|
||||||
|
printf("Compiling kernel...\n");
|
||||||
|
|
||||||
|
fd = open("/boot/tccargs", O_RDONLY);
|
||||||
|
if (fd < 0)
|
||||||
|
fatal("Could not find '%s'", TCCARGS_FILE);
|
||||||
|
len = lseek(fd, 0, SEEK_END);
|
||||||
|
lseek(fd, 0, SEEK_SET);
|
||||||
|
args_buf = malloc(len + 1);
|
||||||
|
len = read(fd, args_buf, len);
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
args_buf[len] = '\0';
|
||||||
|
argc = expand_args(&argv, args_buf);
|
||||||
|
argv[argc] = NULL;
|
||||||
|
free(args_buf);
|
||||||
|
#if 0
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for(i=0;i<argc;i++) {
|
||||||
|
printf("%d: '%s'\n", i, argv[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
ret = main(argc, argv);
|
||||||
|
|
||||||
|
printf("%-50s\n", "");
|
||||||
|
|
||||||
|
printf("Ok, booting the kernel.\n");
|
||||||
|
|
||||||
|
mv->lcount = 0;
|
||||||
|
mv->hcount = get_output_file_size();
|
||||||
|
mv->high_buffer_start = kernel_ptr;
|
||||||
|
|
||||||
|
/* relocate the uncompressed initrd so that the kernel cannot
|
||||||
|
overwrite it */
|
||||||
|
romfs_base1 = ((unsigned long)(mv->high_buffer_start) +
|
||||||
|
mv->hcount + PAGE_SIZE - 1) &
|
||||||
|
~(PAGE_SIZE - 1);
|
||||||
|
if (romfs_base1 < INITRD_MIN_ADDR)
|
||||||
|
romfs_base1 = INITRD_MIN_ADDR;
|
||||||
|
if (!(kernel_ptr >= romfs_base + romfs_len &&
|
||||||
|
(unsigned long)romfs_base >= INITRD_MIN_ADDR) &&
|
||||||
|
(unsigned long)romfs_base < romfs_base1) {
|
||||||
|
memmove((void *)romfs_base1, romfs_base, romfs_len);
|
||||||
|
romfs_base = (void *)romfs_base1;
|
||||||
|
}
|
||||||
|
#ifdef DEBUG_INITRD_ADDR
|
||||||
|
printf("initrd_start=%p initrd_size=%d\n", romfs_base, romfs_len);
|
||||||
|
#endif
|
||||||
|
INITRD_START = (unsigned long)romfs_base;
|
||||||
|
INITRD_SIZE = romfs_len;
|
||||||
|
return 1;
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
#!/bin/sh
|
||||||
|
~/qemu-current/i386-softmmu/qemu -snapshot -user-net -serial stdio \
|
||||||
|
-kernel tccboot \
|
||||||
|
-initrd initrd.img \
|
||||||
|
-append "root=/dev/hda" \
|
||||||
|
-hda example.romfs
|
|
@ -0,0 +1,90 @@
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/types.h>
|
||||||
|
#include <linux/ctype.h>
|
||||||
|
#include <linux/string.h>
|
||||||
|
#include <linux/fcntl.h>
|
||||||
|
#include <linux/fcntl.h>
|
||||||
|
#include <linux/errno.h>
|
||||||
|
#include <linux/time.h>
|
||||||
|
#include <asm/byteorder.h>
|
||||||
|
#include <asm/page.h>
|
||||||
|
|
||||||
|
#define SEEK_SET 0
|
||||||
|
#define SEEK_CUR 1
|
||||||
|
#define SEEK_END 2
|
||||||
|
|
||||||
|
typedef struct FILE {
|
||||||
|
int fd;
|
||||||
|
} FILE;
|
||||||
|
|
||||||
|
struct tm {
|
||||||
|
int tm_sec; /* Seconds. [0-60] (1 leap second) */
|
||||||
|
int tm_min; /* Minutes. [0-59] */
|
||||||
|
int tm_hour; /* Hours. [0-23] */
|
||||||
|
int tm_mday; /* Day. [1-31] */
|
||||||
|
int tm_mon; /* Month. [0-11] */
|
||||||
|
int tm_year; /* Year - 1900. */
|
||||||
|
int tm_wday; /* Day of week. [0-6] */
|
||||||
|
int tm_yday; /* Days in year.[0-365] */
|
||||||
|
int tm_isdst; /* DST. [-1/0/1]*/
|
||||||
|
};
|
||||||
|
|
||||||
|
void *sbrk(int increment);
|
||||||
|
void *malloc(size_t size);
|
||||||
|
void *memalign(size_t alignment, size_t n);
|
||||||
|
void free(void *ptr);
|
||||||
|
int printf(const char *fmt, ...);
|
||||||
|
int fprintf(FILE *f, const char *fmt, ...);
|
||||||
|
uint8_t *load_image(const char *filename);
|
||||||
|
void *realloc(void *ptr, size_t size);
|
||||||
|
|
||||||
|
int open(const char *filename, int access, ...);
|
||||||
|
int read(int fd, void *buf, size_t size);
|
||||||
|
int close(int fd);
|
||||||
|
long lseek(int fd, long offset, int whence);
|
||||||
|
int write(int fd, const void *buf, size_t size);
|
||||||
|
|
||||||
|
FILE *fopen(const char *path, const char *mode);
|
||||||
|
FILE *fdopen(int fildes, const char *mode);
|
||||||
|
int fclose(FILE *stream);
|
||||||
|
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
|
||||||
|
int fputc(int c, FILE *stream);
|
||||||
|
|
||||||
|
long strtol(const char *nptr, char **endptr, int base);
|
||||||
|
long long strtoll(const char *nptr, char **endptr, int base);
|
||||||
|
unsigned long strtoul(const char *nptr, char **endptr, int base);
|
||||||
|
unsigned long long strtoull(const char *nptr, char **endptr, int base);
|
||||||
|
int atoi(const char *s);
|
||||||
|
float strtof(const char *nptr, char **endptr);
|
||||||
|
double strtod(const char *nptr, char **endptr);
|
||||||
|
long double strtold(const char *nptr, char **endptr);
|
||||||
|
double ldexp(double x, int exp);
|
||||||
|
|
||||||
|
int gettimeofday(struct timeval *tv, struct timezone *tz);
|
||||||
|
time_t time(time_t *t);
|
||||||
|
struct tm *localtime(const time_t *timep);
|
||||||
|
|
||||||
|
void exit(int val);
|
||||||
|
void getcwd(char *buf, size_t buf_size);
|
||||||
|
|
||||||
|
typedef int jmp_buf[6];
|
||||||
|
|
||||||
|
int setjmp(jmp_buf buf);
|
||||||
|
void longjmp(jmp_buf buf, int val);
|
||||||
|
|
||||||
|
int main(int argc, char **argv);
|
||||||
|
void fatal(const char *fmt, ...) __attribute__((noreturn)) ;
|
||||||
|
void romfs_init(void);
|
||||||
|
void show_filename(const char *filename);
|
||||||
|
void set_output_file(const char *filename,
|
||||||
|
uint8_t *base, size_t size);
|
||||||
|
long get_output_file_size(void);
|
||||||
|
void putstr(const char *s);
|
||||||
|
int do_gunzip(uint8_t *dest, const uint8_t *src, int src_len);
|
||||||
|
|
||||||
|
extern uint8_t *romfs_base;
|
||||||
|
|
||||||
|
extern int errno;
|
||||||
|
extern FILE *stderr;
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
#include <linux/unistd.h>
|
||||||
|
|
||||||
|
#define __NR_linux_open __NR_open
|
||||||
|
#define __NR_linux_lseek __NR_lseek
|
||||||
|
#define __NR_linux_read __NR_read
|
||||||
|
#define __NR_linux_write __NR_write
|
||||||
|
#define __NR_linux_close __NR_close
|
||||||
|
#define __NR_linux_exit __NR_exit
|
||||||
|
|
||||||
|
_syscall3(int,linux_open,const char *,filename,int,access,int,mode)
|
||||||
|
_syscall3(int,linux_lseek,int,fd,int,offset,int,whence)
|
||||||
|
_syscall3(int,linux_read,int,fd,void *,buf,int,size)
|
||||||
|
_syscall3(int,linux_write,int,fd,const void *,buf,int,size)
|
||||||
|
_syscall1(int,linux_close,int,fd)
|
||||||
|
_syscall1(int,linux_exit,int,val)
|
||||||
|
|
||||||
|
void exit(int val)
|
||||||
|
{
|
||||||
|
linux_exit(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
void putstr(const char *s)
|
||||||
|
{
|
||||||
|
linux_write(1, s, strlen(s));
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *load_image(const char *filename)
|
||||||
|
{
|
||||||
|
int fd, size;
|
||||||
|
uint8_t *p;
|
||||||
|
|
||||||
|
fd = linux_open(filename, O_RDONLY, 0);
|
||||||
|
if (fd < 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
size = linux_lseek(fd, 0, SEEK_END);
|
||||||
|
linux_lseek(fd, 0, SEEK_SET);
|
||||||
|
p = malloc(size + 15);
|
||||||
|
p = (void *)((unsigned long)p & ~15);
|
||||||
|
linux_read(fd, p, size);
|
||||||
|
linux_close(fd);
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,741 @@
|
||||||
|
/*
|
||||||
|
* linux/lib/vsprintf.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 1991, 1992 Linus Torvalds
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */
|
||||||
|
/*
|
||||||
|
* Wirzenius wrote this portably, Torvalds fucked it up :-)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fri Jul 13 2001 Crutcher Dunnavant <crutcher+kernel@datastacks.com>
|
||||||
|
* - changed to provide snprintf and vsnprintf functions
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <linux/types.h>
|
||||||
|
#include <linux/string.h>
|
||||||
|
#include <linux/ctype.h>
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
|
||||||
|
#include <asm/div64.h>
|
||||||
|
#include <asm/page.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* simple_strtoul - convert a string to an unsigned long
|
||||||
|
* @cp: The start of the string
|
||||||
|
* @endp: A pointer to the end of the parsed string will be placed here
|
||||||
|
* @base: The number base to use
|
||||||
|
*/
|
||||||
|
unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base)
|
||||||
|
{
|
||||||
|
unsigned long result = 0,value;
|
||||||
|
|
||||||
|
if (!base) {
|
||||||
|
base = 10;
|
||||||
|
if (*cp == '0') {
|
||||||
|
base = 8;
|
||||||
|
cp++;
|
||||||
|
if ((*cp == 'x') && isxdigit(cp[1])) {
|
||||||
|
cp++;
|
||||||
|
base = 16;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (isxdigit(*cp) &&
|
||||||
|
(value = isdigit(*cp) ? *cp-'0' : toupper(*cp)-'A'+10) < base) {
|
||||||
|
result = result*base + value;
|
||||||
|
cp++;
|
||||||
|
}
|
||||||
|
if (endp)
|
||||||
|
*endp = (char *)cp;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* simple_strtol - convert a string to a signed long
|
||||||
|
* @cp: The start of the string
|
||||||
|
* @endp: A pointer to the end of the parsed string will be placed here
|
||||||
|
* @base: The number base to use
|
||||||
|
*/
|
||||||
|
long simple_strtol(const char *cp,char **endp,unsigned int base)
|
||||||
|
{
|
||||||
|
if(*cp=='-')
|
||||||
|
return -simple_strtoul(cp+1,endp,base);
|
||||||
|
return simple_strtoul(cp,endp,base);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* simple_strtoull - convert a string to an unsigned long long
|
||||||
|
* @cp: The start of the string
|
||||||
|
* @endp: A pointer to the end of the parsed string will be placed here
|
||||||
|
* @base: The number base to use
|
||||||
|
*/
|
||||||
|
unsigned long long simple_strtoull(const char *cp,char **endp,unsigned int base)
|
||||||
|
{
|
||||||
|
unsigned long long result = 0,value;
|
||||||
|
|
||||||
|
if (!base) {
|
||||||
|
base = 10;
|
||||||
|
if (*cp == '0') {
|
||||||
|
base = 8;
|
||||||
|
cp++;
|
||||||
|
if ((*cp == 'x') && isxdigit(cp[1])) {
|
||||||
|
cp++;
|
||||||
|
base = 16;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (isxdigit(*cp) && (value = isdigit(*cp) ? *cp-'0' : (islower(*cp)
|
||||||
|
? toupper(*cp) : *cp)-'A'+10) < base) {
|
||||||
|
result = result*base + value;
|
||||||
|
cp++;
|
||||||
|
}
|
||||||
|
if (endp)
|
||||||
|
*endp = (char *)cp;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* simple_strtoll - convert a string to a signed long long
|
||||||
|
* @cp: The start of the string
|
||||||
|
* @endp: A pointer to the end of the parsed string will be placed here
|
||||||
|
* @base: The number base to use
|
||||||
|
*/
|
||||||
|
long long simple_strtoll(const char *cp,char **endp,unsigned int base)
|
||||||
|
{
|
||||||
|
if(*cp=='-')
|
||||||
|
return -simple_strtoull(cp+1,endp,base);
|
||||||
|
return simple_strtoull(cp,endp,base);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int skip_atoi(const char **s)
|
||||||
|
{
|
||||||
|
int i=0;
|
||||||
|
|
||||||
|
while (isdigit(**s))
|
||||||
|
i = i*10 + *((*s)++) - '0';
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ZEROPAD 1 /* pad with zero */
|
||||||
|
#define SIGN 2 /* unsigned/signed long */
|
||||||
|
#define PLUS 4 /* show plus */
|
||||||
|
#define SPACE 8 /* space if plus */
|
||||||
|
#define LEFT 16 /* left justified */
|
||||||
|
#define SPECIAL 32 /* 0x */
|
||||||
|
#define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */
|
||||||
|
|
||||||
|
static char * number(char * buf, char * end, long long num, int base, int size, int precision, int type)
|
||||||
|
{
|
||||||
|
char c,sign,tmp[66];
|
||||||
|
const char *digits;
|
||||||
|
static const char small_digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
|
||||||
|
static const char large_digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||||
|
int i;
|
||||||
|
|
||||||
|
digits = (type & LARGE) ? large_digits : small_digits;
|
||||||
|
if (type & LEFT)
|
||||||
|
type &= ~ZEROPAD;
|
||||||
|
if (base < 2 || base > 36)
|
||||||
|
return 0;
|
||||||
|
c = (type & ZEROPAD) ? '0' : ' ';
|
||||||
|
sign = 0;
|
||||||
|
if (type & SIGN) {
|
||||||
|
if (num < 0) {
|
||||||
|
sign = '-';
|
||||||
|
num = -num;
|
||||||
|
size--;
|
||||||
|
} else if (type & PLUS) {
|
||||||
|
sign = '+';
|
||||||
|
size--;
|
||||||
|
} else if (type & SPACE) {
|
||||||
|
sign = ' ';
|
||||||
|
size--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (type & SPECIAL) {
|
||||||
|
if (base == 16)
|
||||||
|
size -= 2;
|
||||||
|
else if (base == 8)
|
||||||
|
size--;
|
||||||
|
}
|
||||||
|
i = 0;
|
||||||
|
if (num == 0)
|
||||||
|
tmp[i++]='0';
|
||||||
|
else while (num != 0)
|
||||||
|
tmp[i++] = digits[do_div(num,base)];
|
||||||
|
if (i > precision)
|
||||||
|
precision = i;
|
||||||
|
size -= precision;
|
||||||
|
if (!(type&(ZEROPAD+LEFT))) {
|
||||||
|
while(size-->0) {
|
||||||
|
if (buf <= end)
|
||||||
|
*buf = ' ';
|
||||||
|
++buf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sign) {
|
||||||
|
if (buf <= end)
|
||||||
|
*buf = sign;
|
||||||
|
++buf;
|
||||||
|
}
|
||||||
|
if (type & SPECIAL) {
|
||||||
|
if (base==8) {
|
||||||
|
if (buf <= end)
|
||||||
|
*buf = '0';
|
||||||
|
++buf;
|
||||||
|
} else if (base==16) {
|
||||||
|
if (buf <= end)
|
||||||
|
*buf = '0';
|
||||||
|
++buf;
|
||||||
|
if (buf <= end)
|
||||||
|
*buf = digits[33];
|
||||||
|
++buf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!(type & LEFT)) {
|
||||||
|
while (size-- > 0) {
|
||||||
|
if (buf <= end)
|
||||||
|
*buf = c;
|
||||||
|
++buf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (i < precision--) {
|
||||||
|
if (buf <= end)
|
||||||
|
*buf = '0';
|
||||||
|
++buf;
|
||||||
|
}
|
||||||
|
while (i-- > 0) {
|
||||||
|
if (buf <= end)
|
||||||
|
*buf = tmp[i];
|
||||||
|
++buf;
|
||||||
|
}
|
||||||
|
while (size-- > 0) {
|
||||||
|
if (buf <= end)
|
||||||
|
*buf = ' ';
|
||||||
|
++buf;
|
||||||
|
}
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* vsnprintf - Format a string and place it in a buffer
|
||||||
|
* @buf: The buffer to place the result into
|
||||||
|
* @size: The size of the buffer, including the trailing null space
|
||||||
|
* @fmt: The format string to use
|
||||||
|
* @args: Arguments for the format string
|
||||||
|
*
|
||||||
|
* Call this function if you are already dealing with a va_list.
|
||||||
|
* You probably want snprintf instead.
|
||||||
|
*/
|
||||||
|
int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
|
||||||
|
{
|
||||||
|
int len;
|
||||||
|
unsigned long long num;
|
||||||
|
int i, base;
|
||||||
|
char *str, *end, c;
|
||||||
|
const char *s;
|
||||||
|
|
||||||
|
int flags; /* flags to number() */
|
||||||
|
|
||||||
|
int field_width; /* width of output field */
|
||||||
|
int precision; /* min. # of digits for integers; max
|
||||||
|
number of chars for from string */
|
||||||
|
int qualifier; /* 'h', 'l', or 'L' for integer fields */
|
||||||
|
/* 'z' support added 23/7/1999 S.H. */
|
||||||
|
/* 'z' changed to 'Z' --davidm 1/25/99 */
|
||||||
|
|
||||||
|
|
||||||
|
/* Reject out-of-range values early */
|
||||||
|
if (unlikely((int) size < 0)) {
|
||||||
|
#if 0
|
||||||
|
/* There can be only one.. */
|
||||||
|
static int warn = 1;
|
||||||
|
if (warn) {
|
||||||
|
printk(KERN_WARNING "improper call of vsnprintf!\n");
|
||||||
|
dump_stack();
|
||||||
|
warn = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
str = buf;
|
||||||
|
end = buf + size - 1;
|
||||||
|
|
||||||
|
if (end < buf - 1) {
|
||||||
|
end = ((void *) -1);
|
||||||
|
size = end - buf + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; *fmt ; ++fmt) {
|
||||||
|
if (*fmt != '%') {
|
||||||
|
if (str <= end)
|
||||||
|
*str = *fmt;
|
||||||
|
++str;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* process flags */
|
||||||
|
flags = 0;
|
||||||
|
repeat:
|
||||||
|
++fmt; /* this also skips first '%' */
|
||||||
|
switch (*fmt) {
|
||||||
|
case '-': flags |= LEFT; goto repeat;
|
||||||
|
case '+': flags |= PLUS; goto repeat;
|
||||||
|
case ' ': flags |= SPACE; goto repeat;
|
||||||
|
case '#': flags |= SPECIAL; goto repeat;
|
||||||
|
case '0': flags |= ZEROPAD; goto repeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get field width */
|
||||||
|
field_width = -1;
|
||||||
|
if (isdigit(*fmt))
|
||||||
|
field_width = skip_atoi(&fmt);
|
||||||
|
else if (*fmt == '*') {
|
||||||
|
++fmt;
|
||||||
|
/* it's the next argument */
|
||||||
|
field_width = va_arg(args, int);
|
||||||
|
if (field_width < 0) {
|
||||||
|
field_width = -field_width;
|
||||||
|
flags |= LEFT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get the precision */
|
||||||
|
precision = -1;
|
||||||
|
if (*fmt == '.') {
|
||||||
|
++fmt;
|
||||||
|
if (isdigit(*fmt))
|
||||||
|
precision = skip_atoi(&fmt);
|
||||||
|
else if (*fmt == '*') {
|
||||||
|
++fmt;
|
||||||
|
/* it's the next argument */
|
||||||
|
precision = va_arg(args, int);
|
||||||
|
}
|
||||||
|
if (precision < 0)
|
||||||
|
precision = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get the conversion qualifier */
|
||||||
|
qualifier = -1;
|
||||||
|
if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' ||
|
||||||
|
*fmt =='Z' || *fmt == 'z') {
|
||||||
|
qualifier = *fmt;
|
||||||
|
++fmt;
|
||||||
|
if (qualifier == 'l' && *fmt == 'l') {
|
||||||
|
qualifier = 'L';
|
||||||
|
++fmt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* default base */
|
||||||
|
base = 10;
|
||||||
|
|
||||||
|
switch (*fmt) {
|
||||||
|
case 'c':
|
||||||
|
if (!(flags & LEFT)) {
|
||||||
|
while (--field_width > 0) {
|
||||||
|
if (str <= end)
|
||||||
|
*str = ' ';
|
||||||
|
++str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c = (unsigned char) va_arg(args, int);
|
||||||
|
if (str <= end)
|
||||||
|
*str = c;
|
||||||
|
++str;
|
||||||
|
while (--field_width > 0) {
|
||||||
|
if (str <= end)
|
||||||
|
*str = ' ';
|
||||||
|
++str;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
|
||||||
|
case 's':
|
||||||
|
s = va_arg(args, char *);
|
||||||
|
if ((unsigned long)s < PAGE_SIZE)
|
||||||
|
s = "<NULL>";
|
||||||
|
|
||||||
|
len = strnlen(s, precision);
|
||||||
|
|
||||||
|
if (!(flags & LEFT)) {
|
||||||
|
while (len < field_width--) {
|
||||||
|
if (str <= end)
|
||||||
|
*str = ' ';
|
||||||
|
++str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (i = 0; i < len; ++i) {
|
||||||
|
if (str <= end)
|
||||||
|
*str = *s;
|
||||||
|
++str; ++s;
|
||||||
|
}
|
||||||
|
while (len < field_width--) {
|
||||||
|
if (str <= end)
|
||||||
|
*str = ' ';
|
||||||
|
++str;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
|
||||||
|
case 'p':
|
||||||
|
if (field_width == -1) {
|
||||||
|
field_width = 2*sizeof(void *);
|
||||||
|
flags |= ZEROPAD;
|
||||||
|
}
|
||||||
|
str = number(str, end,
|
||||||
|
(unsigned long) va_arg(args, void *),
|
||||||
|
16, field_width, precision, flags);
|
||||||
|
continue;
|
||||||
|
|
||||||
|
|
||||||
|
case 'n':
|
||||||
|
/* FIXME:
|
||||||
|
* What does C99 say about the overflow case here? */
|
||||||
|
if (qualifier == 'l') {
|
||||||
|
long * ip = va_arg(args, long *);
|
||||||
|
*ip = (str - buf);
|
||||||
|
} else if (qualifier == 'Z' || qualifier == 'z') {
|
||||||
|
size_t * ip = va_arg(args, size_t *);
|
||||||
|
*ip = (str - buf);
|
||||||
|
} else {
|
||||||
|
int * ip = va_arg(args, int *);
|
||||||
|
*ip = (str - buf);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
|
||||||
|
case '%':
|
||||||
|
if (str <= end)
|
||||||
|
*str = '%';
|
||||||
|
++str;
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* integer number formats - set up the flags and "break" */
|
||||||
|
case 'o':
|
||||||
|
base = 8;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'X':
|
||||||
|
flags |= LARGE;
|
||||||
|
case 'x':
|
||||||
|
base = 16;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'd':
|
||||||
|
case 'i':
|
||||||
|
flags |= SIGN;
|
||||||
|
case 'u':
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if (str <= end)
|
||||||
|
*str = '%';
|
||||||
|
++str;
|
||||||
|
if (*fmt) {
|
||||||
|
if (str <= end)
|
||||||
|
*str = *fmt;
|
||||||
|
++str;
|
||||||
|
} else {
|
||||||
|
--fmt;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (qualifier == 'L')
|
||||||
|
num = va_arg(args, long long);
|
||||||
|
else if (qualifier == 'l') {
|
||||||
|
num = va_arg(args, unsigned long);
|
||||||
|
if (flags & SIGN)
|
||||||
|
num = (signed long) num;
|
||||||
|
} else if (qualifier == 'Z' || qualifier == 'z') {
|
||||||
|
num = va_arg(args, size_t);
|
||||||
|
} else if (qualifier == 'h') {
|
||||||
|
num = (unsigned short) va_arg(args, int);
|
||||||
|
if (flags & SIGN)
|
||||||
|
num = (signed short) num;
|
||||||
|
} else {
|
||||||
|
num = va_arg(args, unsigned int);
|
||||||
|
if (flags & SIGN)
|
||||||
|
num = (signed int) num;
|
||||||
|
}
|
||||||
|
str = number(str, end, num, base,
|
||||||
|
field_width, precision, flags);
|
||||||
|
}
|
||||||
|
if (str <= end)
|
||||||
|
*str = '\0';
|
||||||
|
else if (size > 0)
|
||||||
|
/* don't write out a null byte if the buf size is zero */
|
||||||
|
*end = '\0';
|
||||||
|
/* the trailing null byte doesn't count towards the total
|
||||||
|
* ++str;
|
||||||
|
*/
|
||||||
|
return str-buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* snprintf - Format a string and place it in a buffer
|
||||||
|
* @buf: The buffer to place the result into
|
||||||
|
* @size: The size of the buffer, including the trailing null space
|
||||||
|
* @fmt: The format string to use
|
||||||
|
* @...: Arguments for the format string
|
||||||
|
*/
|
||||||
|
int snprintf(char * buf, size_t size, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
va_start(args, fmt);
|
||||||
|
i=vsnprintf(buf,size,fmt,args);
|
||||||
|
va_end(args);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* vsprintf - Format a string and place it in a buffer
|
||||||
|
* @buf: The buffer to place the result into
|
||||||
|
* @fmt: The format string to use
|
||||||
|
* @args: Arguments for the format string
|
||||||
|
*
|
||||||
|
* Call this function if you are already dealing with a va_list.
|
||||||
|
* You probably want sprintf instead.
|
||||||
|
*/
|
||||||
|
int vsprintf(char *buf, const char *fmt, va_list args)
|
||||||
|
{
|
||||||
|
return vsnprintf(buf, (~0U)>>1, fmt, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sprintf - Format a string and place it in a buffer
|
||||||
|
* @buf: The buffer to place the result into
|
||||||
|
* @fmt: The format string to use
|
||||||
|
* @...: Arguments for the format string
|
||||||
|
*/
|
||||||
|
int sprintf(char * buf, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
va_start(args, fmt);
|
||||||
|
i=vsprintf(buf,fmt,args);
|
||||||
|
va_end(args);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* vsscanf - Unformat a buffer into a list of arguments
|
||||||
|
* @buf: input buffer
|
||||||
|
* @fmt: format of buffer
|
||||||
|
* @args: arguments
|
||||||
|
*/
|
||||||
|
int vsscanf(const char * buf, const char * fmt, va_list args)
|
||||||
|
{
|
||||||
|
const char *str = buf;
|
||||||
|
char *next;
|
||||||
|
char digit;
|
||||||
|
int num = 0;
|
||||||
|
int qualifier;
|
||||||
|
int base;
|
||||||
|
int field_width;
|
||||||
|
int is_sign = 0;
|
||||||
|
|
||||||
|
while(*fmt && *str) {
|
||||||
|
/* skip any white space in format */
|
||||||
|
/* white space in format matchs any amount of
|
||||||
|
* white space, including none, in the input.
|
||||||
|
*/
|
||||||
|
if (isspace(*fmt)) {
|
||||||
|
while (isspace(*fmt))
|
||||||
|
++fmt;
|
||||||
|
while (isspace(*str))
|
||||||
|
++str;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* anything that is not a conversion must match exactly */
|
||||||
|
if (*fmt != '%' && *fmt) {
|
||||||
|
if (*fmt++ != *str++)
|
||||||
|
break;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!*fmt)
|
||||||
|
break;
|
||||||
|
++fmt;
|
||||||
|
|
||||||
|
/* skip this conversion.
|
||||||
|
* advance both strings to next white space
|
||||||
|
*/
|
||||||
|
if (*fmt == '*') {
|
||||||
|
while (!isspace(*fmt) && *fmt)
|
||||||
|
fmt++;
|
||||||
|
while (!isspace(*str) && *str)
|
||||||
|
str++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get field width */
|
||||||
|
field_width = -1;
|
||||||
|
if (isdigit(*fmt))
|
||||||
|
field_width = skip_atoi(&fmt);
|
||||||
|
|
||||||
|
/* get conversion qualifier */
|
||||||
|
qualifier = -1;
|
||||||
|
if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' ||
|
||||||
|
*fmt == 'Z' || *fmt == 'z') {
|
||||||
|
qualifier = *fmt;
|
||||||
|
fmt++;
|
||||||
|
}
|
||||||
|
base = 10;
|
||||||
|
is_sign = 0;
|
||||||
|
|
||||||
|
if (!*fmt || !*str)
|
||||||
|
break;
|
||||||
|
|
||||||
|
switch(*fmt++) {
|
||||||
|
case 'c':
|
||||||
|
{
|
||||||
|
char *s = (char *) va_arg(args,char*);
|
||||||
|
if (field_width == -1)
|
||||||
|
field_width = 1;
|
||||||
|
do {
|
||||||
|
*s++ = *str++;
|
||||||
|
} while (--field_width > 0 && *str);
|
||||||
|
num++;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
case 's':
|
||||||
|
{
|
||||||
|
char *s = (char *) va_arg(args, char *);
|
||||||
|
if(field_width == -1)
|
||||||
|
field_width = INT_MAX;
|
||||||
|
/* first, skip leading white space in buffer */
|
||||||
|
while (isspace(*str))
|
||||||
|
str++;
|
||||||
|
|
||||||
|
/* now copy until next white space */
|
||||||
|
while (*str && !isspace(*str) && field_width--) {
|
||||||
|
*s++ = *str++;
|
||||||
|
}
|
||||||
|
*s = '\0';
|
||||||
|
num++;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
case 'n':
|
||||||
|
/* return number of characters read so far */
|
||||||
|
{
|
||||||
|
int *i = (int *)va_arg(args,int*);
|
||||||
|
*i = str - buf;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
case 'o':
|
||||||
|
base = 8;
|
||||||
|
break;
|
||||||
|
case 'x':
|
||||||
|
case 'X':
|
||||||
|
base = 16;
|
||||||
|
break;
|
||||||
|
case 'i':
|
||||||
|
base = 0;
|
||||||
|
case 'd':
|
||||||
|
is_sign = 1;
|
||||||
|
case 'u':
|
||||||
|
break;
|
||||||
|
case '%':
|
||||||
|
/* looking for '%' in str */
|
||||||
|
if (*str++ != '%')
|
||||||
|
return num;
|
||||||
|
continue;
|
||||||
|
default:
|
||||||
|
/* invalid format; stop here */
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* have some sort of integer conversion.
|
||||||
|
* first, skip white space in buffer.
|
||||||
|
*/
|
||||||
|
while (isspace(*str))
|
||||||
|
str++;
|
||||||
|
|
||||||
|
digit = *str;
|
||||||
|
if (is_sign && digit == '-')
|
||||||
|
digit = *(str + 1);
|
||||||
|
|
||||||
|
if (!digit
|
||||||
|
|| (base == 16 && !isxdigit(digit))
|
||||||
|
|| (base == 10 && !isdigit(digit))
|
||||||
|
|| (base == 8 && (!isdigit(digit) || digit > '7'))
|
||||||
|
|| (base == 0 && !isdigit(digit)))
|
||||||
|
break;
|
||||||
|
|
||||||
|
switch(qualifier) {
|
||||||
|
case 'h':
|
||||||
|
if (is_sign) {
|
||||||
|
short *s = (short *) va_arg(args,short *);
|
||||||
|
*s = (short) simple_strtol(str,&next,base);
|
||||||
|
} else {
|
||||||
|
unsigned short *s = (unsigned short *) va_arg(args, unsigned short *);
|
||||||
|
*s = (unsigned short) simple_strtoul(str, &next, base);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'l':
|
||||||
|
if (is_sign) {
|
||||||
|
long *l = (long *) va_arg(args,long *);
|
||||||
|
*l = simple_strtol(str,&next,base);
|
||||||
|
} else {
|
||||||
|
unsigned long *l = (unsigned long*) va_arg(args,unsigned long*);
|
||||||
|
*l = simple_strtoul(str,&next,base);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'L':
|
||||||
|
if (is_sign) {
|
||||||
|
long long *l = (long long*) va_arg(args,long long *);
|
||||||
|
*l = simple_strtoll(str,&next,base);
|
||||||
|
} else {
|
||||||
|
unsigned long long *l = (unsigned long long*) va_arg(args,unsigned long long*);
|
||||||
|
*l = simple_strtoull(str,&next,base);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'Z':
|
||||||
|
case 'z':
|
||||||
|
{
|
||||||
|
size_t *s = (size_t*) va_arg(args,size_t*);
|
||||||
|
*s = (size_t) simple_strtoul(str,&next,base);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (is_sign) {
|
||||||
|
int *i = (int *) va_arg(args, int*);
|
||||||
|
*i = (int) simple_strtol(str,&next,base);
|
||||||
|
} else {
|
||||||
|
unsigned int *i = (unsigned int*) va_arg(args, unsigned int*);
|
||||||
|
*i = (unsigned int) simple_strtoul(str,&next,base);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
num++;
|
||||||
|
|
||||||
|
if (!next)
|
||||||
|
break;
|
||||||
|
str = next;
|
||||||
|
}
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sscanf - Unformat a buffer into a list of arguments
|
||||||
|
* @buf: input buffer
|
||||||
|
* @fmt: formatting of buffer
|
||||||
|
* @...: resulting arguments
|
||||||
|
*/
|
||||||
|
int sscanf(const char * buf, const char * fmt, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
va_start(args,fmt);
|
||||||
|
i = vsscanf(buf,fmt,args);
|
||||||
|
va_end(args);
|
||||||
|
return i;
|
||||||
|
}
|
Loading…
Reference in New Issue