I am working on my own bootloader. I want it to print "Hello world". For some reason, I get an error: Error! E2028: small_code is an undefined reference
Hello! I am working on my own bootloader. I want it to print "Hello world". I have the following code:
main.c:
#define HELLO_STR "\"Hello, world…\""
#define BLACK 0x0
#define WHITE 0xF
typedef unsigned char byte;
#define bool char
#define true 1
#define false 0
int STRLEN_(const char *str) {
int len = 0;
while ((*str) != '\0') {
len++;
}
return len;
}
void printText(
const char *str,
byte inX,
byte inY,
byte inBackgroundColor,
byte inTextColor,
bool inUpdateCursor
)
{
byte textAttribute = ((inTextColor) | (inBackgroundColor << 4));
byte lengthOfString = STRLEN_(str);
__asm {
push bp
mov al, inUpdateCursor
xor bh, bh
mov bl, textAttribute
xor cx, cx
mov cl, lengthOfString
mov dh, inY
mov dl, inX
mov es, word ptr[str + 2]
mov bp, word ptr[str]
mov ah, 13h
int 10h
pop bp
}
}
void clearScreen(void) {
__asm {
mov al, 02h
mov ah, 00h
int 10h
}
}
void showCursor(bool inMode) {
byte flag = inMode ? 0 : 0x32;
__asm {
mov ch, flag
mov cl, 0Ah
mov ah, 01h
int 10h
}
}
void BootMain()
{
clearScreen();
showCursor(false);
printText(
HELLO_STR,
0,
0,
BLACK,
WHITE,
false
);
return;
}
StartPoint.asm:
;------------------------------------------------------------
.286 ; CPU type
;------------------------------------------------------------
.model TINY ; memory of model
;---------------------- EXTERNS -----------------------------
extrn BootMain_:near ; prototype of C func
;------------------------------------------------------------
;------------------------------------------------------------
.code
org 07c00h ; for BootSector
main:
jmp short start ; go to main
nop
;----------------------- CODE SEGMENT -----------------------
start:
cli
mov ax,cs ; Setup segment registers
mov ds,ax ; Make DS correct
mov es,ax ; Make ES correct
mov ss,ax ; Make SS correct
mov bp,7c00h
mov sp,7c00h ; Setup a stack
sti
; start the program
call BootMain_
ret
END main ; End of program
Then I use the following commands to compile it:
wcl.exe -v -mt -s -c -bt=dos -fo=main.obj main.c
& ".\VC152\wasm.exe" -q -0 -fo="StartPoint.obj" ".\StartPoint.asm"
.\VC152\wlink.exe file "StartPoint.obj" file "main.obj" name bootloader.com format dos com option nodefaultlibs option quiet
But when I try to link both files I get the following error: Error! E2028: small_code is an undefined reference
How can I fix that?
From the OpenWatcom reference guide:
small_code If this undefined reference occurs when you are trying to create a 16-bit application, we have saved you many hours of debugging! The reason for this undefined reference is that the "main" entry point has been compiled for a big code model (in any one of medium, large, or huge memory models).
...
There may be another cause of this problem, the "main" function must be entered in lower case letters ("Main" or "MAIN" are not identified as being the same as "main" by the compiler). The compiler will identify the module that contains the definition of the function "main" by creating the public definition of either small_code or big_code depending on the memory model it was compiled in.
So this is your issue in a nutshell: no main function, so Watcom's internal machinery doesn't work as supposed. You can either rename your "main" function to actual main and let that machinery work, or provide a public symbol _small_code_
somewhere.